<commit_before>// Generated on 2013-11-21 using generator-angular 0.6.0-rc.1
'use strict';

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'

module.exports = function (grunt) {
    require('load-grunt-tasks')(grunt);

    grunt.initConfig({
        yeoman: {
            // configurable paths
            app: require('./bower.json').appPath || 'app',
            dist: 'dist'
        },
        env: {
            prod: {}
        },
        preprocess: {
            prod: {
                src : '<%= yeoman.dist %>/index.html',
                dest : '<%= yeoman.dist %>/index.html'
            }
        },
        watch: {
            styles: {
                files: ['<%= yeoman.app %>/styles/{,*/}*.css'],
                tasks: ['copy:styles', 'autoprefixer']
            },
            livereload: {
                options: {
                    livereload: '<%= connect.options.livereload %>'
                },
                files: [
                    '<%= yeoman.app %>/{,*/}*.html',
                    '.tmp/styles/{,*/}*.css',
                    '{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js',
                    '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
                ]
            }
        },
        autoprefixer: {
            options: ['last 1 version'],
            dist: {
                files: [{
                    expand: true,
                    cwd: '.tmp/styles/',
                    src: '{,*/}*.css',
                    dest: '.tmp/styles/'
                }]
            }
        },
        connect: {
            options: {
                port: 9000,
                // Change this to '0.0.0.0' to access the server from outside.
                hostname: '0.0.0.0',
                livereload: 35729
            },
            livereload: {
                options: {
                    open: true,
                    base: [
                        '.tmp',
                        '<%= yeoman.app %>'
                    ]
                }
            },
            test: {
                options: {
                    port: 9001,
                    base: [
                        '.tmp',
                        'test',
                        '<%= yeoman.app %>'
                    ]
                }
            },
            dist: {
                options: {
                    base: '<%= yeoman.dist %>'
                }
            }
        },
        clean: {
            dist: {
                files: [{
                    dot: true,
                    src: [
                        '.tmp',
                        '<%= yeoman.dist %>/*',
                        '!<%= yeoman.dist %>/.git*'
                    ]
                }]
            },
            server: '.tmp'
        },
        jshint: {
            options: {
                jshintrc: '.jshintrc',
                reporter: require('jshint-stylish')
            },
            all: [
                'Gruntfile.js',
                '<%= yeoman.app %>/scripts/{,*/}*.js'
            ]
        },
        // not used since Uglify task does concat,
        // but still available if needed
        /*concat: {
            dist: {}
        },*/
        rev: {
            dist: {
                files: {
                    src: [
                        '<%= yeoman.dist %>/scripts/{,*/}*.js',
                        '<%= yeoman.dist %>/styles/{,*/}*.css',
                        '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
                        '<%= yeoman.dist %>/styles/fonts/*'
                    ]
                }
            }
        },
        useminPrepare: {
            html: '<%= yeoman.app %>/index.html',
            options: {
                dest: '<%= yeoman.dist %>'
            }
        },
        usemin: {
            html: ['<%= yeoman.dist %>/{,*/}*.html'],
            css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
            options: {
                assetsDirs: ['<%= yeoman.dist %>']
            }
        },
        cssmin: {
            // By default, your `index.html` <!-- Usemin Block --> will take care of
            // minification. This option is pre-configured if you do not wish to use
            // Usemin blocks.
            // dist: {
            //     files: {
            //         '<%= yeoman.dist %>/styles/main.css': [
            //             '.tmp/styles/{,*/}*.css',
            //             '<%= yeoman.app %>/styles/{,*/}*.css'
            //         ]
            //     }
            // }
        },
        htmlmin: {
            dist: {
                options: {
                    /*removeCommentsFromCDATA: true,
                    // https://github.com/yeoman/grunt-usemin/issues/44
                    //collapseWhitespace: true,
                    collapseBooleanAttributes: true,
                    removeAttributeQuotes: true,
                    removeRedundantAttributes: true,
                    useShortDoctype: true,
                    removeEmptyAttributes: true,
                    removeOptionalTags: true*/
                },
                files: [{
                    expand: true,
                    cwd: '<%= yeoman.app %>',
                    src: ['*.html', 'views/*.html'],
                    dest: '<%= yeoman.dist %>'
                }]
            }
        },
        // Put files not handled in other tasks here
        copy: {
            dist: {
                files: [{
                    expand: true,
                    dot: true,
                    cwd: '<%= yeoman.app %>',
                    dest: '<%= yeoman.dist %>',
                    src: [
                        '*.{ico,png,txt}',
                        '.htaccess',
                        'bower_components/**/*',
                        'images/{,*/}*.{gif,webp}',
                        'fonts/*'
                    ]
                }, {
                    expand: true,
                    cwd: '.tmp/images',
                    dest: '<%= yeoman.dist %>/images',
                    src: [
                        'generated/*'
                    ]
                }]
            },
            styles: {
                expand: true,
                cwd: '<%= yeoman.app %>/styles',
                dest: '.tmp/styles/',
                src: '{,*/}*.css'
            }
        },
        concurrent: {
            server: [
                'copy:styles'
            ],
            test: [
                'copy:styles'
            ],
            dist: [
                'copy:styles',
                'htmlmin'
            ]
        },
        karma: {
            e2e: {
                configFile: 'karma-e2e.conf.js'
            }
        },
        ngmin: {
            dist: {
                files: [{
                    expand: true,
                    cwd: '.tmp/concat/scripts',
                    src: '*.js',
                    dest: '.tmp/concat/scripts'
                }]
            }
        },
        uglify: {
            dist: {
                files: {
                    '<%= yeoman.dist %>/scripts/scripts.js': [
                        '<%= yeoman.dist %>/scripts/scripts.js'
                    ]
                }
            }
        }
    });

    grunt.registerTask('server', function (target) {
        if (target === 'dist') {
            return grunt.task.run(['build', 'connect:dist:keepalive']);
        }

        grunt.task.run([
            'clean:server',
            'concurrent:server',
            'autoprefixer',
            'connect:livereload',
            'watch'
        ]);
    });

    grunt.registerTask('test', [
        'clean:server',
        'concurrent:test',
        'autoprefixer',
        'connect:test',
        'karma'
    ]);

    grunt.registerTask('build', [
        'clean:dist',
        'env:prod',
        'useminPrepare',
        'concurrent:dist',
        'autoprefixer',
        'concat',
        'ngmin',
        'copy:dist',
        'cssmin',
        'uglify',
        'rev',
        'usemin',
        'preprocess:prod'
    ]);

    grunt.registerTask('default', [
        'jshint',
        'test',
        'build'
    ]);
};
<commit_msg>Fixed a strange dependency issue during grunt build<commit_after>// Generated on 2013-11-21 using generator-angular 0.6.0-rc.1
'use strict';

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'

module.exports = function (grunt) {
    require('load-grunt-tasks')(grunt);

    grunt.initConfig({
        yeoman: {
            // configurable paths
            app: require('./bower.json').appPath || 'app',
            dist: 'dist'
        },
        env: {
            prod: {}
        },
        preprocess: {
            prod: {
                src : '<%= yeoman.dist %>/index.html',
                dest : '<%= yeoman.dist %>/index.html'
            }
        },
        watch: {
            styles: {
                files: ['<%= yeoman.app %>/styles/{,*/}*.css'],
                tasks: ['copy:styles', 'autoprefixer']
            },
            livereload: {
                options: {
                    livereload: '<%= connect.options.livereload %>'
                },
                files: [
                    '<%= yeoman.app %>/{,*/}*.html',
                    '.tmp/styles/{,*/}*.css',
                    '{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js',
                    '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
                ]
            }
        },
        autoprefixer: {
            options: ['last 1 version'],
            dist: {
                files: [{
                    expand: true,
                    cwd: '.tmp/styles/',
                    src: '{,*/}*.css',
                    dest: '.tmp/styles/'
                }]
            }
        },
        connect: {
            options: {
                port: 9000,
                // Change this to '0.0.0.0' to access the server from outside.
                hostname: '0.0.0.0',
                livereload: 35729
            },
            livereload: {
                options: {
                    open: true,
                    base: [
                        '.tmp',
                        '<%= yeoman.app %>'
                    ]
                }
            },
            test: {
                options: {
                    port: 9001,
                    base: [
                        '.tmp',
                        'test',
                        '<%= yeoman.app %>'
                    ]
                }
            },
            dist: {
                options: {
                    base: '<%= yeoman.dist %>'
                }
            }
        },
        clean: {
            dist: {
                files: [{
                    dot: true,
                    src: [
                        '.tmp',
                        '<%= yeoman.dist %>/*',
                        '!<%= yeoman.dist %>/.git*'
                    ]
                }]
            },
            server: '.tmp'
        },
        jshint: {
            options: {
                jshintrc: '.jshintrc',
                reporter: require('jshint-stylish')
            },
            all: [
                'Gruntfile.js',
                '<%= yeoman.app %>/scripts/{,*/}*.js'
            ]
        },
        // not used since Uglify task does concat,
        // but still available if needed
        /*concat: {
            dist: {}
        },*/
        rev: {
            dist: {
                files: {
                    src: [
                        '<%= yeoman.dist %>/scripts/{,*/}*.js',
                        '<%= yeoman.dist %>/styles/{,*/}*.css',
                        '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
                        '<%= yeoman.dist %>/styles/fonts/*'
                    ]
                }
            }
        },
        useminPrepare: {
            html: '<%= yeoman.app %>/index.html',
            options: {
                dest: '<%= yeoman.dist %>'
            }
        },
        usemin: {
            html: ['<%= yeoman.dist %>/{,*/}*.html'],
            css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
            options: {
                assetsDirs: ['<%= yeoman.dist %>']
            }
        },
        cssmin: {
            // By default, your `index.html` <!-- Usemin Block --> will take care of
            // minification. This option is pre-configured if you do not wish to use
            // Usemin blocks.
            // dist: {
            //     files: {
            //         '<%= yeoman.dist %>/styles/main.css': [
            //             '.tmp/styles/{,*/}*.css',
            //             '<%= yeoman.app %>/styles/{,*/}*.css'
            //         ]
            //     }
            // }
        },
        htmlmin: {
            dist: {
                options: {
                    /*removeCommentsFromCDATA: true,
                    // https://github.com/yeoman/grunt-usemin/issues/44
                    //collapseWhitespace: true,
                    collapseBooleanAttributes: true,
                    removeAttributeQuotes: true,
                    removeRedundantAttributes: true,
                    useShortDoctype: true,
                    removeEmptyAttributes: true,
                    removeOptionalTags: true*/
                },
                files: [{
                    expand: true,
                    cwd: '<%= yeoman.app %>',
                    src: ['*.html', 'views/*.html'],
                    dest: '<%= yeoman.dist %>'
                }]
            }
        },
        // Put files not handled in other tasks here
        copy: {
            dist: {
                files: [{
                    expand: true,
                    dot: true,
                    cwd: '<%= yeoman.app %>',
                    dest: '<%= yeoman.dist %>',
                    src: [
                        '*.{ico,png,txt}',
                        '.htaccess',
                        'bower_components/**/*',
                        'images/{,*/}*.{gif,webp}',
                        'fonts/*'
                    ]
                }, {
                    expand: true,
                    cwd: '.tmp/images',
                    dest: '<%= yeoman.dist %>/images',
                    src: [
                        'generated/*'
                    ]
                }]
            },
            styles: {
                expand: true,
                cwd: '<%= yeoman.app %>/styles',
                dest: '.tmp/styles/',
                src: '{,*/}*.css'
            }
        },
        concurrent: {
            server: [
                'copy:styles'
            ],
            test: [
                'copy:styles'
            ],
            dist: [
                'copy:styles',
                'htmlmin'
            ]
        },
        karma: {
            e2e: {
                configFile: 'karma-e2e.conf.js'
            }
        },
        ngmin: {
            dist: {
                files: [{
                    expand: true,
                    cwd: '.tmp/concat/scripts',
                    src: '*.js',
                    dest: '.tmp/concat/scripts'
                }]
            }
        },
        uglify: {
            dist: {
                files: {
                    '<%= yeoman.dist %>/scripts/scripts.js': [
                        '<%= yeoman.dist %>/scripts/scripts.js'
                    ]
                }
            }
        }
    });

    grunt.registerTask('server', function (target) {
        if (target === 'dist') {
            return grunt.task.run(['build', 'connect:dist:keepalive']);
        }

        grunt.task.run([
            'clean:server',
            'concurrent:server',
            'autoprefixer',
            'connect:livereload',
            'watch'
        ]);
    });

    grunt.registerTask('test', [
        'clean:server',
        'concurrent:test',
        'autoprefixer',
        'connect:test',
        'karma'
    ]);

    grunt.registerTask('build', [
        'clean:dist',
        'env:prod',
        'useminPrepare',
        'concurrent:dist',
        'autoprefixer',
        'concat',
        'ngmin',
        'copy:dist',
        'cssmin',
        'uglify:generated',
        'uglify',
        'rev',
        'usemin',
        'preprocess:prod'
    ]);

    grunt.registerTask('default', [
        'jshint',
        'test',
        'build'
    ]);
};
<|endoftext|>


<commit_before>// ==UserScript==
// @name           Add Google site search
// @namespace      curipha
// @description    Add site search form to all pages.
// @include        http://*
// @include        https://*
// @exclude        http://*.google.tld/*
// @exclude        https://*.google.tld/*
// @version        0.1.0
// @grant          GM_addStyle
// @noframes
// ==/UserScript==

(function(){
  if (document.contentType !== 'text/html') return;

  var css =
  // "z-index" should be less than 255 because an indicator of Autopagerize is at 256.
    '#userjs-add_google { background: #ddd; padding: 10px; line-height: 1; min-width: 200px; border: 2px solid #ccc; position: fixed; top: 0; right: 0; z-index: 255; } '+
    '#userjs-add_google form { margin: 0 !important; } '+
    '#userjs-add_google input { font: 18px monospace !important; padding: 0.3em !important; display: inline !important; width: 14em !important; } '+
    '#userjs-add_google input[type="submit"] { display: none !important; } '+
    '#userjs-add_google_del { color: #000 !important; font: bold 24px sans-serif !important; margin-right: 8px !important; cursor: pointer !important; }';
  GM_addStyle(css);

  var form = document.createElement('div');
  form.id = 'userjs-add_google';
  form.style.opacity = 0;
  form.innerHTML = ' ';
  form.addEventListener('mouseover', init, false);
  form.addEventListener('mouseout', hide, false);
  document.body.appendChild(form);

  function init() {
    this.innerHTML =
      '<form action="https://www.google.com/search" method="get" accept-charset="UTF-8" target="_top">'+
      '×'+
      '<input type="text" name="q" placeholder="' + document.domain + ' を検索" /><input type="submit" value="Search" />'+
      '<input type="hidden" name="as_sitesearch" value="' + document.domain + '" />'+
      '<input type="hidden" name="safe" value="off" />'+
      '</form>';

    this.style.opacity = 1;
    this.removeEventListener('mouseover', init, false);
    this.addEventListener('mouseover', show, false);

    document.getElementById('userjs-add_google_del').addEventListener('click', remove, false);
  }
  function remove() { document.body.removeChild(form); }

  function hide() { form.style.opacity = 0; }
  function show() { form.style.opacity = 1; }
})();
<commit_msg>Ignore page style more aggressively<commit_after>// ==UserScript==
// @name           Add Google site search
// @namespace      curipha
// @description    Add site search form to all pages.
// @include        http://*
// @include        https://*
// @exclude        http://*.google.tld/*
// @exclude        https://*.google.tld/*
// @version        0.1.1
// @grant          GM_addStyle
// @noframes
// ==/UserScript==

(function(){
  if (document.contentType !== 'text/html') return;

  var css =
  // "z-index" should be less than 255 because an indicator of Autopagerize is at 256.
    '#userjs-add_google { background: #ddd; padding: 10px; line-height: 1; min-width: 200px; border: 2px solid #ccc; position: fixed; top: 0; right: 0; z-index: 255; } '+
    '#userjs-add_google form { margin: 0 !important; padding: 0 !important; } '+
    '#userjs-add_google input { font: 18px monospace !important; margin: 0 !important; padding: 0.3em !important; display: inline !important; width: 14em !important; height: auto !important; } '+
    '#userjs-add_google input[type="submit"] { display: none !important; } '+
    '#userjs-add_google_del { color: #000 !important; font: bold 24px sans-serif !important; margin-right: 8px !important; cursor: pointer !important; }';
  GM_addStyle(css);

  var form = document.createElement('div');
  form.id = 'userjs-add_google';
  form.style.opacity = 0;
  form.innerHTML = ' ';
  form.addEventListener('mouseover', init, false);
  form.addEventListener('mouseout', hide, false);
  document.body.appendChild(form);

  function init() {
    this.innerHTML =
      '<form action="https://www.google.com/search" method="get" accept-charset="UTF-8" target="_top">'+
      '×'+
      '<input type="text" name="q" placeholder="' + document.domain + ' を検索" /><input type="submit" value="Search" />'+
      '<input type="hidden" name="as_sitesearch" value="' + document.domain + '" />'+
      '<input type="hidden" name="safe" value="off" />'+
      '</form>';

    this.style.opacity = 1;
    this.removeEventListener('mouseover', init, false);
    this.addEventListener('mouseover', show, false);

    document.getElementById('userjs-add_google_del').addEventListener('click', remove, false);
  }
  function remove() { document.body.removeChild(form); }

  function hide() { form.style.opacity = 0; }
  function show() { form.style.opacity = 1; }
})();
<|endoftext|>


<commit_before>/* globals Testem */

export { default as QUnitAdapter, nonTestDoneCallback } from './adapter';
export { loadTests } from './test-loader';

import './qunit-configuration';

if (typeof Testem !== 'undefined') {
  Testem.hookIntoTestFramework();
}

import { _backburner } from '@ember/runloop';
import { resetOnerror, getTestMetadata } from '@ember/test-helpers';
import { loadTests } from './test-loader';
import Ember from 'ember';
import * as QUnit from 'qunit';
import QUnitAdapter from './adapter';
import {
  setupContext,
  teardownContext,
  setupRenderingContext,
  setupApplicationContext,
  validateErrorHandler,
} from '@ember/test-helpers';
import { installTestNotIsolatedHook } from './test-isolation-validation';

let waitForSettled = true;

export function setupTest(hooks, _options) {
  let options = { waitForSettled, ..._options };

  hooks.beforeEach(function (assert) {
    let testMetadata = getTestMetadata(this);
    testMetadata.framework = 'qunit';

    return setupContext(this, options).then(() => {
      let originalPauseTest = this.pauseTest;
      this.pauseTest = function QUnit_pauseTest() {
        assert.timeout(-1); // prevent the test from timing out

        // This is a temporary work around for
        // https://github.com/emberjs/ember-qunit/issues/496 this clears the
        // timeout that would fail the test when it hits the global testTimeout
        // value.
        clearTimeout(QUnit.config.timeout);
        return originalPauseTest.call(this);
      };
    });
  });

  hooks.afterEach(function () {
    return teardownContext(this, options);
  });
}

export function setupRenderingTest(hooks, _options) {
  let options =
    _options === undefined
      ? { waitForSettled }
      : assign({ waitForSettled }, _options);

  setupTest(hooks, options);

  hooks.beforeEach(function () {
    return setupRenderingContext(this);
  });
}

export function setupApplicationTest(hooks, _options) {
  let options =
    _options === undefined
      ? { waitForSettled }
      : assign({ waitForSettled }, _options);

  setupTest(hooks, options);

  hooks.beforeEach(function () {
    return setupApplicationContext(this);
  });
}

/**
   Uses current URL configuration to setup the test container.

   * If `?nocontainer` is set, the test container will be hidden.
   * If `?devmode` or `?fullscreencontainer` is set, the test container will be
     made full screen.

   @method setupTestContainer
 */
export function setupTestContainer() {
  let testContainer = document.getElementById('ember-testing-container');
  if (!testContainer) {
    return;
  }

  let params = QUnit.urlParams;
  let containerVisibility = params.nocontainer ? 'hidden' : 'visible';

  if (params.devmode || params.fullscreencontainer) {
    testContainer.className = ' full-screen';
  }

  testContainer.style.visibility = containerVisibility;
}

/**
   Instruct QUnit to start the tests.
   @method startTests
 */
export function startTests() {
  QUnit.start();
}

/**
   Sets up the `Ember.Test` adapter for usage with QUnit 2.x.

   @method setupTestAdapter
 */
export function setupTestAdapter() {
  Ember.Test.adapter = QUnitAdapter.create();
}

/**
  Ensures that `Ember.testing` is set to `true` before each test begins
  (including `before` / `beforeEach`), and reset to `false` after each test is
  completed. This is done via `QUnit.testStart` and `QUnit.testDone`.

 */
export function setupEmberTesting() {
  QUnit.testStart(() => {
    Ember.testing = true;
  });

  QUnit.testDone(() => {
    Ember.testing = false;
  });
}

/**
  Ensures that `Ember.onerror` (if present) is properly configured to re-throw
  errors that occur while `Ember.testing` is `true`.
*/
export function setupEmberOnerrorValidation() {
  QUnit.module('ember-qunit: Ember.onerror validation', function () {
    QUnit.test('Ember.onerror is functioning properly', function (assert) {
      assert.expect(1);
      let result = validateErrorHandler();
      assert.ok(
        result.isValid,
        `Ember.onerror handler with invalid testing behavior detected. An Ember.onerror handler _must_ rethrow exceptions when \`Ember.testing\` is \`true\` or the test suite is unreliable. See https://git.io/vbine for more details.`
      );
    });
  });
}

export function setupResetOnerror() {
  QUnit.testDone(resetOnerror);
}

export function setupTestIsolationValidation(delay) {
  waitForSettled = false;
  _backburner.DEBUG = true;
  QUnit.on('testStart', () => installTestNotIsolatedHook(delay));
}

/**
   @method start
   @param {Object} [options] Options to be used for enabling/disabling behaviors
   @param {Boolean} [options.loadTests] If `false` tests will not be loaded automatically.
   @param {Boolean} [options.setupTestContainer] If `false` the test container will not
   be setup based on `devmode`, `dockcontainer`, or `nocontainer` URL params.
   @param {Boolean} [options.startTests] If `false` tests will not be automatically started
   (you must run `QUnit.start()` to kick them off).
   @param {Boolean} [options.setupTestAdapter] If `false` the default Ember.Test adapter will
   not be updated.
   @param {Boolean} [options.setupEmberTesting] `false` opts out of the
   default behavior of setting `Ember.testing` to `true` before all tests and
   back to `false` after each test will.
   @param {Boolean} [options.setupEmberOnerrorValidation] If `false` validation
   of `Ember.onerror` will be disabled.
   @param {Boolean} [options.setupTestIsolationValidation] If `false` test isolation validation
   will be disabled.
   @param {Number} [options.testIsolationValidationDelay] When using
   setupTestIsolationValidation this number represents the maximum amount of
   time in milliseconds that is allowed _after_ the test is completed for all
   async to have been completed. The default value is 50.
 */
export function start(options = {}) {
  if (options.loadTests !== false) {
    loadTests();
  }

  if (options.setupTestContainer !== false) {
    setupTestContainer();
  }

  if (options.setupTestAdapter !== false) {
    setupTestAdapter();
  }

  if (options.setupEmberTesting !== false) {
    setupEmberTesting();
  }

  if (options.setupEmberOnerrorValidation !== false) {
    setupEmberOnerrorValidation();
  }

  if (
    typeof options.setupTestIsolationValidation !== 'undefined' &&
    options.setupTestIsolationValidation !== false
  ) {
    setupTestIsolationValidation(options.testIsolationValidationDelay);
  }

  if (options.startTests !== false) {
    startTests();
  }

  setupResetOnerror();
}
<commit_msg>Fix more Ember.assign<commit_after>/* globals Testem */

export { default as QUnitAdapter, nonTestDoneCallback } from './adapter';
export { loadTests } from './test-loader';

import './qunit-configuration';

if (typeof Testem !== 'undefined') {
  Testem.hookIntoTestFramework();
}

import { _backburner } from '@ember/runloop';
import { resetOnerror, getTestMetadata } from '@ember/test-helpers';
import { loadTests } from './test-loader';
import Ember from 'ember';
import * as QUnit from 'qunit';
import QUnitAdapter from './adapter';
import {
  setupContext,
  teardownContext,
  setupRenderingContext,
  setupApplicationContext,
  validateErrorHandler,
} from '@ember/test-helpers';
import { installTestNotIsolatedHook } from './test-isolation-validation';

let waitForSettled = true;

export function setupTest(hooks, _options) {
  let options = { waitForSettled, ..._options };

  hooks.beforeEach(function (assert) {
    let testMetadata = getTestMetadata(this);
    testMetadata.framework = 'qunit';

    return setupContext(this, options).then(() => {
      let originalPauseTest = this.pauseTest;
      this.pauseTest = function QUnit_pauseTest() {
        assert.timeout(-1); // prevent the test from timing out

        // This is a temporary work around for
        // https://github.com/emberjs/ember-qunit/issues/496 this clears the
        // timeout that would fail the test when it hits the global testTimeout
        // value.
        clearTimeout(QUnit.config.timeout);
        return originalPauseTest.call(this);
      };
    });
  });

  hooks.afterEach(function () {
    return teardownContext(this, options);
  });
}

export function setupRenderingTest(hooks, _options) {
  let options = { waitForSettled, ..._options };

  setupTest(hooks, options);

  hooks.beforeEach(function () {
    return setupRenderingContext(this);
  });
}

export function setupApplicationTest(hooks, _options) {
  let options = { waitForSettled, ..._options };

  setupTest(hooks, options);

  hooks.beforeEach(function () {
    return setupApplicationContext(this);
  });
}

/**
   Uses current URL configuration to setup the test container.

   * If `?nocontainer` is set, the test container will be hidden.
   * If `?devmode` or `?fullscreencontainer` is set, the test container will be
     made full screen.

   @method setupTestContainer
 */
export function setupTestContainer() {
  let testContainer = document.getElementById('ember-testing-container');
  if (!testContainer) {
    return;
  }

  let params = QUnit.urlParams;
  let containerVisibility = params.nocontainer ? 'hidden' : 'visible';

  if (params.devmode || params.fullscreencontainer) {
    testContainer.className = ' full-screen';
  }

  testContainer.style.visibility = containerVisibility;
}

/**
   Instruct QUnit to start the tests.
   @method startTests
 */
export function startTests() {
  QUnit.start();
}

/**
   Sets up the `Ember.Test` adapter for usage with QUnit 2.x.

   @method setupTestAdapter
 */
export function setupTestAdapter() {
  Ember.Test.adapter = QUnitAdapter.create();
}

/**
  Ensures that `Ember.testing` is set to `true` before each test begins
  (including `before` / `beforeEach`), and reset to `false` after each test is
  completed. This is done via `QUnit.testStart` and `QUnit.testDone`.

 */
export function setupEmberTesting() {
  QUnit.testStart(() => {
    Ember.testing = true;
  });

  QUnit.testDone(() => {
    Ember.testing = false;
  });
}

/**
  Ensures that `Ember.onerror` (if present) is properly configured to re-throw
  errors that occur while `Ember.testing` is `true`.
*/
export function setupEmberOnerrorValidation() {
  QUnit.module('ember-qunit: Ember.onerror validation', function () {
    QUnit.test('Ember.onerror is functioning properly', function (assert) {
      assert.expect(1);
      let result = validateErrorHandler();
      assert.ok(
        result.isValid,
        `Ember.onerror handler with invalid testing behavior detected. An Ember.onerror handler _must_ rethrow exceptions when \`Ember.testing\` is \`true\` or the test suite is unreliable. See https://git.io/vbine for more details.`
      );
    });
  });
}

export function setupResetOnerror() {
  QUnit.testDone(resetOnerror);
}

export function setupTestIsolationValidation(delay) {
  waitForSettled = false;
  _backburner.DEBUG = true;
  QUnit.on('testStart', () => installTestNotIsolatedHook(delay));
}

/**
   @method start
   @param {Object} [options] Options to be used for enabling/disabling behaviors
   @param {Boolean} [options.loadTests] If `false` tests will not be loaded automatically.
   @param {Boolean} [options.setupTestContainer] If `false` the test container will not
   be setup based on `devmode`, `dockcontainer`, or `nocontainer` URL params.
   @param {Boolean} [options.startTests] If `false` tests will not be automatically started
   (you must run `QUnit.start()` to kick them off).
   @param {Boolean} [options.setupTestAdapter] If `false` the default Ember.Test adapter will
   not be updated.
   @param {Boolean} [options.setupEmberTesting] `false` opts out of the
   default behavior of setting `Ember.testing` to `true` before all tests and
   back to `false` after each test will.
   @param {Boolean} [options.setupEmberOnerrorValidation] If `false` validation
   of `Ember.onerror` will be disabled.
   @param {Boolean} [options.setupTestIsolationValidation] If `false` test isolation validation
   will be disabled.
   @param {Number} [options.testIsolationValidationDelay] When using
   setupTestIsolationValidation this number represents the maximum amount of
   time in milliseconds that is allowed _after_ the test is completed for all
   async to have been completed. The default value is 50.
 */
export function start(options = {}) {
  if (options.loadTests !== false) {
    loadTests();
  }

  if (options.setupTestContainer !== false) {
    setupTestContainer();
  }

  if (options.setupTestAdapter !== false) {
    setupTestAdapter();
  }

  if (options.setupEmberTesting !== false) {
    setupEmberTesting();
  }

  if (options.setupEmberOnerrorValidation !== false) {
    setupEmberOnerrorValidation();
  }

  if (
    typeof options.setupTestIsolationValidation !== 'undefined' &&
    options.setupTestIsolationValidation !== false
  ) {
    setupTestIsolationValidation(options.testIsolationValidationDelay);
  }

  if (options.startTests !== false) {
    startTests();
  }

  setupResetOnerror();
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, describe, it, expect, beforeEach, afterEach, waits, waitsFor, waitsForDone, runs, $, brackets, waitsForDone, spyOn, tinycolor, KeyEvent */

define(function (require, exports, module) {
    "use strict";

    var StaticServer    = require("main"),
        NodeConnection  = brackets.getModule("utils/NodeConnection"),
        FileUtils       = brackets.getModule("file/FileUtils"),
        SpecRunnerUtils = brackets.getModule("spec/SpecRunnerUtils");

    var testFolder     = FileUtils.getNativeModuleDirectoryPath(module) + "/unittest-files/";

    describe("StaticServer", function () {

        // Unit tests for the underlying node server.
        describe("StaticServerDomain", function () {
            var nodeConnection;

            beforeEach(function () {
                runs(function () {
                    nodeConnection = new NodeConnection();
                    waitsForDone(nodeConnection.connect(false), "connecting to node server");
                });

                runs(function () {
                    var domainPromise = new $.Deferred(),
                        retries = 0;

                    function waitForDomain() {
                        if (nodeConnection.domains.staticServer) {
                            domainPromise.resolve();
                        } else {
                            retries++;
                            if (retries >= 5) {
                                domainPromise.reject();
                            } else {
                                setTimeout(waitForDomain, 100);
                            }
                        }
                    }

                    waitForDomain();
                    waitsForDone(domainPromise, "waiting for StaticServer domain to load");
                });
            });

            afterEach(function () {
                nodeConnection.disconnect();
                nodeConnection = null;
            });

            function makeBaseUrl(serverInfo) {
                return "http://" + serverInfo.address + ":" + serverInfo.port;
            }

            it("should start a static server on the given folder", function () {
                var serverInfo, path = testFolder + "folder1";
                runs(function () {
                    nodeConnection.domains.staticServer.getServer(path)
                        .done(function (info) {
                            serverInfo = info;
                        });
                });

                waitsFor(function () { return serverInfo; }, "waiting for static server to start");

                runs(function () {
                    expect(serverInfo.address).toBe("127.0.0.1");
                    expect(Number(serverInfo.port)).toBeGreaterThan(0);

                    waitsForDone(nodeConnection.domains.staticServer.closeServer(path),
                                 "waiting for static server to close");
                });
            });

            it("should serve the text of a file in the given folder", function () {
                var serverInfo, text, path = testFolder + "folder1";
                runs(function () {
                    nodeConnection.domains.staticServer.getServer(path)
                        .done(function (info) {
                            serverInfo = info;
                        });
                });

                waitsFor(function () { return serverInfo; }, "waiting for static server to start");

                runs(function () {
                    $.get(makeBaseUrl(serverInfo) + "/index.txt")
                        .done(function (data) {
                            text = data;
                        });
                });

                waitsFor(function () { return text; }, "waiting for text from server");

                runs(function () {
                    expect(text).toBe("This is a file in folder 1.");

                    waitsForDone(nodeConnection.domains.staticServer.closeServer(path),
                                 "waiting for static server to close");
                });
            });

            it("should create separate servers for different folders", function () {
                var serverInfo1, serverInfo2,
                    path1 = testFolder + "folder1", path2 = testFolder + "folder2";
                runs(function () {
                    nodeConnection.domains.staticServer.getServer(path1)
                        .done(function (info) {
                            serverInfo1 = info;
                        });
                    nodeConnection.domains.staticServer.getServer(path2)
                        .done(function (info) {
                            serverInfo2 = info;
                        });
                });

                waitsFor(function () { return serverInfo1 && serverInfo2; }, "waiting for static servers to start");

                runs(function () {
                    expect(serverInfo1.port).not.toBe(serverInfo2.port);

                    waitsForDone(nodeConnection.domains.staticServer.closeServer(path1),
                                 "waiting for static server 1 to close");
                    waitsForDone(nodeConnection.domains.staticServer.closeServer(path2),
                                 "waiting for static server 2 to close");
                });
            });

            it("should keep a previous server alive after creating a new server", function () {
                var serverInfo1, serverInfo2,
                    path1 = testFolder + "folder1", path2 = testFolder + "folder2",
                    text1, text2;
                runs(function () {
                    nodeConnection.domains.staticServer.getServer(path1)
                        .done(function (info) {
                            serverInfo1 = info;
                        });
                    nodeConnection.domains.staticServer.getServer(path2)
                        .done(function (info) {
                            serverInfo2 = info;
                        });
                });

                waitsFor(function () { return serverInfo1 && serverInfo2; }, "waiting for static servers to start");

                runs(function () {
                    $.get(makeBaseUrl(serverInfo1) + "/index.txt")
                        .done(function (data) {
                            text1 = data;
                        });
                    $.get(makeBaseUrl(serverInfo2) + "/index.txt")
                        .done(function (data) {
                            text2 = data;
                        });
                });

                waitsFor(function () { return text1 && text2; }, "waiting for text from servers");

                runs(function () {
                    expect(text1).toBe("This is a file in folder 1.");
                    expect(text2).toBe("This is a file in folder 2.");

                    waitsForDone(nodeConnection.domains.staticServer.closeServer(path1),
                                 "waiting for static server 1 to close");
                    waitsForDone(nodeConnection.domains.staticServer.closeServer(path2),
                                 "waiting for static server 2 to close");
                });
            });
        });

        // Unit tests for the StaticServerProvider that wraps the underlying node server.
        describe("StaticServerProvider", function () {
            var brackets,
                ProjectManager,
                StaticServer;

            beforeEach(function () {
                runs(function () {
                    SpecRunnerUtils.createTestWindowAndRun(this, function (testWindow) {
                        // Load module instances from brackets.test
                        brackets = testWindow.brackets;
                        ProjectManager = testWindow.brackets.test.ProjectManager;
                    });
                });

                waitsFor(function () {
                    return brackets.test.extensions.StaticServer !== undefined;
                }, "StaticServer to fully initialize");

                runs(function () {
                    StaticServer = brackets.test.extensions.StaticServer;
                });
            });

            afterEach(function () {
                SpecRunnerUtils.closeTestWindow();
            });

            it("should have initialized the static server provider immediately after launch", function () {
                // Note: the goal is to test this as quickly as possible. We can't
                // actually test immediately when appReady fires because that happens
                // asynchronously in our test window. But we know this will run shortly
                // after appReady fires. There's no way to test it synchronously
                // because appReady is the event that gives us access to StaticServer in
                // the test window.
                expect(StaticServer._getStaticServerProvider()).toBeTruthy();
            });

            it("shoud only serve html files that are in the project file hierarchy", function () {
                waitsForDone(ProjectManager.openProject(testFolder), "opens test folder in ProjectManager");

                runs(function () {
                    var provider = StaticServer._getStaticServerProvider();

                    // should not serve files outside project hierarchy
                    expect(provider.canServe("/foo.html")).toBe(false);

                    // should not serve non-HTML files inside hierarchy
                    expect(provider.canServe(testFolder + "foo.jpg")).toBe(false);

                    // should serve .htm files inside hierarchy
                    expect(provider.canServe(testFolder + "foo.htm")).toBe(true);

                    // should serve .html files inside hierarchy
                    expect(provider.canServe(testFolder + "foo.html")).toBe(true);

                    // should serve .HTML files inside hierarchy
                    expect(provider.canServe(testFolder + "foo.HTML")).toBe(true);

                    // should serve root of hierarchy
                    expect(provider.canServe(testFolder)).toBe(true);

                });

            });

            it("should decline serving if not connected to node", function () {
                var nodeConnectionDeferred;
                runs(function () {
                    nodeConnectionDeferred = StaticServer._getNodeConnectionDeferred();
                });

                waitsFor(function () {
                    return nodeConnectionDeferred.isResolved();
                }, "should be connected to node");

                runs(function () {
                    nodeConnectionDeferred.done(function (nodeConnection) {
                        // this will be run synchronously because of the waitsFor above
                        nodeConnection.disconnect();
                    });
                    expect(StaticServer._getStaticServerProvider().canServe(testFolder + "foo.html")).toBe(false);
                });

            });

        });
    });
});
<commit_msg>increase connection timeouts because connecting takes longer on windows<commit_after>/*
 * Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, describe, it, expect, beforeEach, afterEach, waits, waitsFor, waitsForDone, runs, $, brackets, waitsForDone, spyOn, tinycolor, KeyEvent */

define(function (require, exports, module) {
    "use strict";

    var StaticServer    = require("main"),
        NodeConnection  = brackets.getModule("utils/NodeConnection"),
        FileUtils       = brackets.getModule("file/FileUtils"),
        SpecRunnerUtils = brackets.getModule("spec/SpecRunnerUtils");

    var testFolder     = FileUtils.getNativeModuleDirectoryPath(module) + "/unittest-files/";

    var CONNECT_TIMEOUT = 5000;

    describe("StaticServer", function () {

        // Unit tests for the underlying node server.
        describe("StaticServerDomain", function () {
            var nodeConnection;

            beforeEach(function () {
                runs(function () {
                    nodeConnection = new NodeConnection();
                    waitsForDone(nodeConnection.connect(false), "connecting to node server", CONNECT_TIMEOUT);
                });

                runs(function () {
                    var domainPromise = new $.Deferred(),
                        retries = 0;

                    function waitForDomain() {
                        if (nodeConnection.domains.staticServer) {
                            domainPromise.resolve();
                        } else {
                            retries++;
                            if (retries >= 5) {
                                domainPromise.reject();
                            } else {
                                setTimeout(waitForDomain, 100);
                            }
                        }
                    }

                    waitForDomain();
                    waitsForDone(domainPromise, "waiting for StaticServer domain to load");
                });
            });

            afterEach(function () {
                nodeConnection.disconnect();
                nodeConnection = null;
            });

            function makeBaseUrl(serverInfo) {
                return "http://" + serverInfo.address + ":" + serverInfo.port;
            }

            it("should start a static server on the given folder", function () {
                var serverInfo, path = testFolder + "folder1";
                runs(function () {
                    nodeConnection.domains.staticServer.getServer(path)
                        .done(function (info) {
                            serverInfo = info;
                        });
                });

                waitsFor(function () { return serverInfo; }, "waiting for static server to start");

                runs(function () {
                    expect(serverInfo.address).toBe("127.0.0.1");
                    expect(Number(serverInfo.port)).toBeGreaterThan(0);

                    waitsForDone(nodeConnection.domains.staticServer.closeServer(path),
                                 "waiting for static server to close");
                });
            });

            it("should serve the text of a file in the given folder", function () {
                var serverInfo, text, path = testFolder + "folder1";
                runs(function () {
                    nodeConnection.domains.staticServer.getServer(path)
                        .done(function (info) {
                            serverInfo = info;
                        });
                });

                waitsFor(function () { return serverInfo; }, "waiting for static server to start");

                runs(function () {
                    $.get(makeBaseUrl(serverInfo) + "/index.txt")
                        .done(function (data) {
                            text = data;
                        });
                });

                waitsFor(function () { return text; }, "waiting for text from server");

                runs(function () {
                    expect(text).toBe("This is a file in folder 1.");

                    waitsForDone(nodeConnection.domains.staticServer.closeServer(path),
                                 "waiting for static server to close");
                });
            });

            it("should create separate servers for different folders", function () {
                var serverInfo1, serverInfo2,
                    path1 = testFolder + "folder1", path2 = testFolder + "folder2";
                runs(function () {
                    nodeConnection.domains.staticServer.getServer(path1)
                        .done(function (info) {
                            serverInfo1 = info;
                        });
                    nodeConnection.domains.staticServer.getServer(path2)
                        .done(function (info) {
                            serverInfo2 = info;
                        });
                });

                waitsFor(function () { return serverInfo1 && serverInfo2; }, "waiting for static servers to start");

                runs(function () {
                    expect(serverInfo1.port).not.toBe(serverInfo2.port);

                    waitsForDone(nodeConnection.domains.staticServer.closeServer(path1),
                                 "waiting for static server 1 to close");
                    waitsForDone(nodeConnection.domains.staticServer.closeServer(path2),
                                 "waiting for static server 2 to close");
                });
            });

            it("should keep a previous server alive after creating a new server", function () {
                var serverInfo1, serverInfo2,
                    path1 = testFolder + "folder1", path2 = testFolder + "folder2",
                    text1, text2;
                runs(function () {
                    nodeConnection.domains.staticServer.getServer(path1)
                        .done(function (info) {
                            serverInfo1 = info;
                        });
                    nodeConnection.domains.staticServer.getServer(path2)
                        .done(function (info) {
                            serverInfo2 = info;
                        });
                });

                waitsFor(function () { return serverInfo1 && serverInfo2; }, "waiting for static servers to start");

                runs(function () {
                    $.get(makeBaseUrl(serverInfo1) + "/index.txt")
                        .done(function (data) {
                            text1 = data;
                        });
                    $.get(makeBaseUrl(serverInfo2) + "/index.txt")
                        .done(function (data) {
                            text2 = data;
                        });
                });

                waitsFor(function () { return text1 && text2; }, "waiting for text from servers");

                runs(function () {
                    expect(text1).toBe("This is a file in folder 1.");
                    expect(text2).toBe("This is a file in folder 2.");

                    waitsForDone(nodeConnection.domains.staticServer.closeServer(path1),
                                 "waiting for static server 1 to close");
                    waitsForDone(nodeConnection.domains.staticServer.closeServer(path2),
                                 "waiting for static server 2 to close");
                });
            });
        });

        // Unit tests for the StaticServerProvider that wraps the underlying node server.
        describe("StaticServerProvider", function () {
            var brackets,
                ProjectManager,
                StaticServer;

            beforeEach(function () {
                runs(function () {
                    SpecRunnerUtils.createTestWindowAndRun(this, function (testWindow) {
                        // Load module instances from brackets.test
                        brackets = testWindow.brackets;
                        ProjectManager = testWindow.brackets.test.ProjectManager;
                    });
                });

                waitsFor(function () {
                    return brackets.test.extensions.StaticServer !== undefined;
                }, "StaticServer to fully initialize");

                runs(function () {
                    StaticServer = brackets.test.extensions.StaticServer;
                    waitsForDone(StaticServer._getNodeConnectionDeferred(), "connecting to node server", CONNECT_TIMEOUT);
                });
            });

            afterEach(function () {
                SpecRunnerUtils.closeTestWindow();
            });

            it("should have initialized the static server provider immediately after launch", function () {
                // Note: the goal is to test this as quickly as possible. We can't
                // actually test immediately when appReady fires because that happens
                // asynchronously in our test window. But we know this will run shortly
                // after appReady fires. There's no way to test it synchronously
                // because appReady is the event that gives us access to StaticServer in
                // the test window.
                expect(StaticServer._getStaticServerProvider()).toBeTruthy();
            });

            it("shoud only serve html files that are in the project file hierarchy", function () {
                waitsForDone(ProjectManager.openProject(testFolder), "opens test folder in ProjectManager");

                runs(function () {
                    var provider = StaticServer._getStaticServerProvider();

                    // should not serve files outside project hierarchy
                    expect(provider.canServe("/foo.html")).toBe(false);

                    // should not serve non-HTML files inside hierarchy
                    expect(provider.canServe(testFolder + "foo.jpg")).toBe(false);

                    // should serve .htm files inside hierarchy
                    expect(provider.canServe(testFolder + "foo.htm")).toBe(true);

                    // should serve .html files inside hierarchy
                    expect(provider.canServe(testFolder + "foo.html")).toBe(true);

                    // should serve .HTML files inside hierarchy
                    expect(provider.canServe(testFolder + "foo.HTML")).toBe(true);

                    // should serve root of hierarchy
                    expect(provider.canServe(testFolder)).toBe(true);

                });

            });

            it("should decline serving if not connected to node", function () {
                var nodeConnectionDeferred;
                runs(function () {
                    nodeConnectionDeferred = StaticServer._getNodeConnectionDeferred();
                });

                waitsFor(function () {
                    return nodeConnectionDeferred.isResolved();
                }, "should be connected to node");

                runs(function () {
                    nodeConnectionDeferred.done(function (nodeConnection) {
                        // this will be run synchronously because of the waitsFor above
                        nodeConnection.disconnect();
                    });
                    expect(StaticServer._getStaticServerProvider().canServe(testFolder + "foo.html")).toBe(false);
                });

            });

        });
    });
});
<|endoftext|>


<commit_before>import { get, getWithDefault } from '@ember/object';
import { isEmpty, isPresent, isNone } from '@ember/utils';
import { getOwner } from '@ember/application';

import override from '@onehilltech/override';
import decorator from '@onehilltech/decorator';

function noOp () {}

const bearerErrorCodes = [
  'invalid_token',
  'unknown_token',
  'token_disabled',
  'unknown_client',
  'client_disabled',
  'unknown_account',
  'account_disabled'
];

function authenticated (target, name, descriptor, options = {}) {
  const {
    scope,
    redirectParamName = 'redirect',
    accessTokenParamName = 'access_token',
    skipAccountLookup = false,
    secretOrPublicKey,
    verifyOptions,
    signInAction = 'redirect'
  } = options;

  let {
    signInRoute
  } = options;

  /**
   * Check that the current user is authenticated.
   *
   * @param transition
   * @private
   */
  target.prototype._checkSignedIn = async function (transition) {
    const { to: { queryParams = {}}} = transition;
    const accessToken = queryParams[accessTokenParamName];

    if (isPresent (accessToken)) {
      // There is an access token in the query parameters. This takes precedence over the
      // status of the session.
      const options = {
        verified: this.verified || noOp,
        skipAccountLookup,
        secretOrPublicKey,
        verifyOptions
      };

      try {
        await this.session.openFrom (accessToken, options);
        return true;
      }
      catch (err) {
        return false;
      }
    }
    else if (this.session.isSignedIn) {
      // The user is signed into the current session. Let's check if the access token has expired. if
      // so, then we need to refresh the access token. If we fail at refreshing the token, the let's
      // reset the session before continuing.

      if (this.session.accessToken.isExpired) {
        try {
          await this.session.refresh ();
          return true;
        }
        catch (err) {
          this.session.reset ();
          return false;
        }
      }
      else {
        return true;
      }
    }
    else {
      return false;
    }
  }

  // Make sure there is an actions object.
  target.actions = target.actions || {};

  // Define the error handling routine/action.
  target.actions.error = async function (reason) {
    const errors = get (reason, 'errors');

    if (isEmpty (errors)) {
      return true;
    }

    for (let i = 0, len = errors.length; i < len; ++ i) {
      const { code, detail } = errors[i];

      if (bearerErrorCodes.includes (code)) {
        if (this.session.isSignedIn) {
          // Redirect to sign in page, allowing the user to redirect back to the
          // original page. But, do not support the back button. We aren't going
          // to attempt to sign out the user from the current session.

          const ENV = getOwner (this).resolveRegistration ('config:environment');
          signInRoute = signInRoute || getWithDefault (ENV, 'gatekeeper.signInRoute', 'sign-in');

          if (signInAction === 'redirect') {
            // Show the error message, and then redirect to the sign in route.

            this.snackbar.show ({ message: detail });
            this.replaceWith (signInRoute);
          }
          else if (signInAction === 'prompt') {
            // Show the error message, and prompt the user to sign in.

            this.snackbar.show ({ message: detail, action: { label: 'Sign in', click: () => this.replaceWith (signInRoute)}});
          }
          else {
            // Let's just show the error message to the user, but we are not going
            // to take any action at this point in time.

            this.snackbar.show ({ message: detail });
          }
        }
        else {
          // We are just going to reset the gatekeeper client at this point in time
          // It will force the client to reauthenticate itself.

          this.session.gatekeeper.reset ();
        }

        // Let's break out of this for-loop.
        break;
      }
    }

    return true;
  }

  /**
   * beforeModel
   *
   * We override the beforeModel() method to check if the user is authenticated before
   * moving to the model() method. If the user is not authenticated, we redirect the
   * user to the signInRoute, if applicable.
   */
  override.async (target.prototype, 'beforeModel', async function (transition) {
    function routeToSignIn (route) {
      const ENV = getOwner (route).resolveRegistration ('config:environment');
      signInRoute = signInRoute || get (ENV, 'gatekeeper.signInRoute');

      if (isNone (signInRoute)) {
        return false;
      }

      // Set the redirect to route so we can come back to this route when the
      // user has signed in.
      const { intent : { url }} = transition;
      const options = { queryParams: { [redirectParamName]: encodeURI (url) } };

      route.replaceWith (signInRoute, options);

      return true;
    }

    function forceSessionReset (route) {
      // Reset the session and then go to the sign in route.
      route.session.reset ();
      routeToSignIn (route);

      route.snackbar.show ({message: 'We had to sign out because your session is no longer valid.', dismiss: true});
    }

    try {
      const isSignedIn = await this._checkSignedIn (transition);

      if (isSignedIn) {
        const authorized = isEmpty (scope) || this.session.accessToken.supports (scope);

        if (!authorized && isPresent (target.actions.unauthorized)) {
          return transition.trigger ('unauthorized', transition);
        }
        else {
          return this._super.call (this, ...arguments);
        }
      }
      else if (!routeToSignIn (this)) {
        return this._super.call (this, ...arguments);
      }
    }
    catch (err) {
      return forceSessionReset (this);
    }
  });
}

export default decorator (authenticated);
<commit_msg>fix: error handler did not propogate to parent routes<commit_after>import { get, getWithDefault } from '@ember/object';
import { isEmpty, isPresent, isNone } from '@ember/utils';
import { getOwner } from '@ember/application';

import override from '@onehilltech/override';
import decorator from '@onehilltech/decorator';

function noOp () {}

const bearerErrorCodes = [
  'invalid_token',
  'unknown_token',
  'token_disabled',
  'unknown_client',
  'client_disabled',
  'unknown_account',
  'account_disabled'
];

function authenticated (target, name, descriptor, options = {}) {
  const {
    scope,
    redirectParamName = 'redirect',
    accessTokenParamName = 'access_token',
    skipAccountLookup = false,
    secretOrPublicKey,
    verifyOptions,
    signInAction = 'redirect'
  } = options;

  let {
    signInRoute
  } = options;

  /**
   * Check that the current user is authenticated.
   *
   * @param transition
   * @private
   */
  target.prototype._checkSignedIn = async function (transition) {
    const { to: { queryParams = {}}} = transition;
    const accessToken = queryParams[accessTokenParamName];

    if (isPresent (accessToken)) {
      // There is an access token in the query parameters. This takes precedence over the
      // status of the session.
      const options = {
        verified: this.verified || noOp,
        skipAccountLookup,
        secretOrPublicKey,
        verifyOptions
      };

      try {
        await this.session.openFrom (accessToken, options);
        return true;
      }
      catch (err) {
        return false;
      }
    }
    else if (this.session.isSignedIn) {
      // The user is signed into the current session. Let's check if the access token has expired. if
      // so, then we need to refresh the access token. If we fail at refreshing the token, the let's
      // reset the session before continuing.

      if (this.session.accessToken.isExpired) {
        try {
          await this.session.refresh ();
          return true;
        }
        catch (err) {
          this.session.reset ();
          return false;
        }
      }
      else {
        return true;
      }
    }
    else {
      return false;
    }
  }

  // Make sure there is an actions object.
  target.actions = target.actions || {};

  // Define the error handling routine/action.
  target.actions.error = async function (reason) {
    const errors = get (reason, 'errors');

    if (isEmpty (errors)) {
      return true;
    }

    for (let i = 0, len = errors.length; i < len; ++ i) {
      const { code, detail } = errors[i];

      if (bearerErrorCodes.includes (code)) {
        if (this.session.isSignedIn) {
          // Redirect to sign in page, allowing the user to redirect back to the
          // original page. But, do not support the back button. We aren't going
          // to attempt to sign out the user from the current session.

          const ENV = getOwner (this).resolveRegistration ('config:environment');
          signInRoute = signInRoute || getWithDefault (ENV, 'gatekeeper.signInRoute', 'sign-in');

          if (signInAction === 'redirect') {
            // Show the error message, and then redirect to the sign in route.

            this.snackbar.show ({ message: detail });
            this.replaceWith (signInRoute);
          }
          else if (signInAction === 'prompt') {
            // Show the error message, and prompt the user to sign in.

            this.snackbar.show ({ message: detail, action: { label: 'Sign in', click: () => this.replaceWith (signInRoute)}});
          }
          else {
            // Let's just show the error message to the user, but we are not going
            // to take any action at this point in time.

            this.snackbar.show ({ message: detail });
          }
        }
        else {
          // We are just going to reset the gatekeeper client at this point in time
          // It will force the client to reauthenticate itself.

          this.session.gatekeeper.reset ();
        }

        // Let's break out of this for-loop.
        break;
      }
    }

    return true;
  }

  override.async (target.prototype, 'beforeModel', async function (transition) {
    function routeToSignIn (route) {
      const ENV = getOwner (route).resolveRegistration ('config:environment');
      signInRoute = signInRoute || get (ENV, 'gatekeeper.signInRoute');

      if (isNone (signInRoute)) {
        return false;
      }

      // Set the redirect to route so we can come back to this route when the
      // user has signed in.
      const { intent : { url }} = transition;
      const options = { queryParams: { [redirectParamName]: encodeURI (url) } };

      route.replaceWith (signInRoute, options);

      return true;
    }

    function forceSessionReset (route) {
      // Reset the session and then go to the sign in route.
      route.session.reset ();
      routeToSignIn (route);

      route.snackbar.show ({message: 'We had to sign out because your session is no longer valid.', dismiss: true});
    }

    try {
      const isSignedIn = await this._checkSignedIn (transition);

      if (isSignedIn) {
        const authorized = isEmpty (scope) || this.session.accessToken.supports (scope);

        if (!authorized && isPresent (target.actions.unauthorized)) {
          return transition.trigger ('unauthorized', transition);
        }
        else {
          return this._super.call (this, ...arguments);
        }
      }
      else if (!routeToSignIn (this)) {
        return this._super.call (this, ...arguments);
      }
    }
    catch (err) {
      return forceSessionReset (this);
    }
  });
}

export default decorator (authenticated);
<|endoftext|>


<commit_before>import Route from '@ember/routing/route';
import { getOwner } from '@ember/application';

/*
  Creates an aliased form of a method that properly resolves external routes.
*/
function externalAlias(methodName) {
  return function _externalAliasMethod(routeName, ...args) {
    let externalRoute = getOwner(this)._getExternalRoute(routeName);
    return this.router[methodName](externalRoute, ...args);
  };
}

Route.reopen({
  transitionToExternal: externalAlias('transitionTo'),
  replaceWithExternal: externalAlias('replaceWith'),
});
<commit_msg>fix(route-ext): try `Route#_router` and `Route#router`<commit_after>import Route from '@ember/routing/route';
import { getOwner } from '@ember/application';

/*
  Creates an aliased form of a method that properly resolves external routes.
*/
function externalAlias(methodName) {
  return function _externalAliasMethod(routeName, ...args) {
    let externalRoute = getOwner(this)._getExternalRoute(routeName);
    let router = this._router || this.router;
    return router[methodName](externalRoute, ...args);
  };
}

Route.reopen({
  transitionToExternal: externalAlias('transitionTo'),
  replaceWithExternal: externalAlias('replaceWith'),
});
<|endoftext|>


<commit_before>/*
  backgrid-select-all
  http://github.com/wyuenho/backgrid

  Copyright (c) 2013 Jimmy Yuen Ho Wong
  Licensed under the MIT @license.
*/
(function (window, $, _, Backbone, Backgrid)  {

  var SelectRowCell = Backgrid.Extension.SelectRowCell = Backbone.View.extend({

    className: "select-row-cell",

    tagName: "td",

    events: {
      "change": "onChange"
    },

    initialize: function (options) {

      this.column = options.column;
      if (!(this.column instanceof Backgrid.Column)) {
        this.column = new Backgrid.Column(this.column);
      }

      this.listenTo(this.model, "select", function (model, selected) {
        this.$el.find(":checkbox").prop("checked", selected).change();
      });

    },

    onChange: function (e) {
      this.model.trigger("selected", this.model, $(e.target).prop("checked"));
    },

    render: function () {
      this.$el.empty().append("<input type='checkbox' />");
      return this;
    }

  });

  Backgrid.Extension.SelectAllHeaderCell = SelectRowCell.extend({

    className: "select-all-header-cell",

    tagName: "th",

    initialize: function (options) {

      this.column = options.column;
      if (!(this.column instanceof Backgrid.Column)) {
        this.column = new Backgrid.Column(this.column);
      }

      var collection = this.collection;
      this.listenTo(collection, "selected", function (model, selected) {
        if (!selected) {
          this.$el.find(":checkbox").prop("checked", selected);
          this.allSelected = selected;
        }
      });

      this.listenTo(Backbone, "backgrid:refresh", function () {
        if (this.allSelected) {
          collection.each(function (model) {
            model.trigger("select", model, true);
          });
        }
      });

      this.allSelected = false;
    },

    onChange: function (e) {
      var selected = $(e.target).prop("checked");

      this.collection.each(function (model) {
        model.trigger("select", model, selected);
      });

      this.allSelected = selected;
    }

  });

}(window, jQuery, _, Backbone, Backgrid));
<commit_msg>Deselect select all checkbox when collection is empty<commit_after>/*
  backgrid-select-all
  http://github.com/wyuenho/backgrid

  Copyright (c) 2013 Jimmy Yuen Ho Wong
  Licensed under the MIT @license.
*/
(function (window, $, _, Backbone, Backgrid)  {

  var SelectRowCell = Backgrid.Extension.SelectRowCell = Backbone.View.extend({

    className: "select-row-cell",

    tagName: "td",

    events: {
      "change": "onChange"
    },

    initialize: function (options) {

      this.column = options.column;
      if (!(this.column instanceof Backgrid.Column)) {
        this.column = new Backgrid.Column(this.column);
      }

      this.listenTo(this.model, "select", function (model, selected) {
        this.$el.find(":checkbox").prop("checked", selected).change();
      });

    },

    onChange: function (e) {
      this.model.trigger("selected", this.model, $(e.target).prop("checked"));
    },

    render: function () {
      this.$el.empty().append("<input type='checkbox' />");
      return this;
    }

  });

  Backgrid.Extension.SelectAllHeaderCell = SelectRowCell.extend({

    className: "select-all-header-cell",

    tagName: "th",

    initialize: function (options) {

      this.column = options.column;
      if (!(this.column instanceof Backgrid.Column)) {
        this.column = new Backgrid.Column(this.column);
      }

      var collection = this.collection;
      this.listenTo(collection, "selected", function (model, selected) {
        if (!selected) {
          this.$el.find(":checkbox").prop("checked", selected);
          this.allSelected = selected;
        }
      });

      this.listenTo(collection, "all", function () {
        if (!collection.length) {
          this.$el.find("input[type='checkbox']").prop("checked", false);
        }
      });

      this.listenTo(Backbone, "backgrid:refresh", function () {
        if (this.allSelected) {
          collection.each(function (model) {
            model.trigger("select", model, true);
          });
        }
      });

      this.allSelected = false;
    },

    onChange: function (e) {
      var selected = $(e.target).prop("checked");

      this.collection.each(function (model) {
        model.trigger("select", model, selected);
      });

      this.allSelected = selected;
    }

  });

}(window, jQuery, _, Backbone, Backgrid));
<|endoftext|>


<commit_before>/*
  Our Transform type is always respresented relative to
  `transform-origin: 0px 0px`. This is different from the browser's
  own `transform` property, which will vary based on the present value
  of `transform-origin`, and which defaults to `50% 50%`. I am
  standardizing on zero because it disentangles our coordinate system
  from the size of the element, which can vary over time.

  Conceptually, each of our Transforms is a 2d affine transformation
  representd as a 3x3 matrix:

      a c tx
      b d ty
      0 0  1
*/

export default class Transform {
  constructor(a, b, c, d, tx, ty) {
    // WARNING: never mutate an existing Transform. Some of them are
    // shared. Operations need to return new Transforms instead.
    this.a = a;
    this.b = b;
    this.c = c;
    this.d = d;
    this.tx = tx;
    this.ty = ty;
  }
  serialize() {
    if (this.isIdentity()) {
      return 'none';
    }
    return `matrix(${this.a}, ${this.b}, ${this.c}, ${this.d}, ${this.tx}, ${this.ty})`;
  }

  // See the comment below on `const identity`.
  isIdentity() {
    return this === identity || (
      this.a === 1 &&
        this.b === 0 &&
        this.c === 0 &&
        this.d === 1 &&
        this.tx === 0 &&
        this.ty === 0
    );
  }

  mult(other) {
    // This is deliberately not isIdentity(). I'm optimizing for the
    // case where there was no preexisting transform at all.
    if (this === identity) { return other; }
    if (other === identity) { return this; }
    return new Transform(
      this.a * other.a + this.c * other.b,
      this.b * other.a + this.d * other.b,
      this.a * other.c + this.c * other.d,
      this.b * other.c + this.d * other.d,
      this.a * other.tx + this.c * other.ty + this.tx,
      this.b * other.tx + this.d * other.ty + this.ty
    );
  }
}

// WARNING: this constant matrix exists as an optimization. But not
// every no-op transform triple-equals this value. If you apply two
// transforms that cancel each other out, you will get an identity
// matrix but it will not triple-equal this one. And that is OK: we
// use the triple-equality as an optimization only, not for
// correctness.
//
// The optimization should be worthwhile because the majority of
// things start out with no preexisting Transform, which we can
// represent as `identity`, which will make identity.mult(something) a
// no-op, etc.
export const identity = new Transform(1, 0, 0, 1, 0, 0);

const matrixPattern = /matrix\((.*)\)/;

function parseTransform(matrixString) {
  let match = matrixPattern.exec(matrixString);
  if (!match) {
    return identity;
  }
  return new Transform(...match[1].split(',').map(parseFloat));
}

function parseOrigin(originString) {
  return originString.split(' ').map(parseFloat);
}

/**
  Returns a Transform instance representing the cumulative CSS
  transform of this element and all its ancestors.

  @function cumulativeTransform
  @hide
  @param {HTMLElement} elt
  @return {Transform}
*/
export function cumulativeTransform(elt) {
  let accumulator = null;
  while (elt && elt.nodeType === 1) {
    let transform = ownTransform(elt);
    if (transform !== identity && !transform.isIdentity()) {
      if (accumulator) {
        accumulator = transform.mult(accumulator);
      } else {
        accumulator = transform;
      }
    }
    elt = elt.parentElement;
  }
  return accumulator || identity;
}

/**
  Returns a Transform instance representing the CSS transform of this
  element.

 * @function ownTransform
 * @param {HTMLElement} elt
 * @return {Transform} instance representing this element's css transform property.
 */
export function ownTransform(elt) {
  let eltStyles = window.getComputedStyle(elt);
  let t = eltStyles.transform !== '' ? eltStyles.transform : elt.style.transform;
  if (t === 'none') {
    // This constant value is an optimization, and we rely on that in
    // cumulativeTransform
    return identity;
  }
  let matrix = parseTransform(t);
  if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) {
    // If there is any rotation, scaling, or skew we need to do it within the context of transform-origin.
    let origin = eltStyles.transformOrigin !== '' ? eltStyles.transformOrigin : elt.style.transformOrigin;
    let [originX, originY] = parseOrigin(origin);
    if (originX === 0 && originY === 0) {
      // transform origin is at 0,0 so it will have no effect, so we're done.
      return matrix;
    }

    return (new Transform(1, 0, 0, 1, originX, originY)).mult(matrix).mult(new Transform(1, 0, 0, 1, -originX, -originY));
  } else {
    // This case is an optimization for when there is only translation.
    return matrix;
  }
}
<commit_msg>don't serialize identity transform as "none"<commit_after>/*
  Our Transform type is always respresented relative to
  `transform-origin: 0px 0px`. This is different from the browser's
  own `transform` property, which will vary based on the present value
  of `transform-origin`, and which defaults to `50% 50%`. I am
  standardizing on zero because it disentangles our coordinate system
  from the size of the element, which can vary over time.

  Conceptually, each of our Transforms is a 2d affine transformation
  representd as a 3x3 matrix:

      a c tx
      b d ty
      0 0  1
*/

export default class Transform {
  constructor(a, b, c, d, tx, ty) {
    // WARNING: never mutate an existing Transform. Some of them are
    // shared. Operations need to return new Transforms instead.
    this.a = a;
    this.b = b;
    this.c = c;
    this.d = d;
    this.tx = tx;
    this.ty = ty;
  }
  serialize() {
    return `matrix(${this.a}, ${this.b}, ${this.c}, ${this.d}, ${this.tx}, ${this.ty})`;
  }

  // See the comment below on `const identity`.
  isIdentity() {
    return this === identity || (
      this.a === 1 &&
        this.b === 0 &&
        this.c === 0 &&
        this.d === 1 &&
        this.tx === 0 &&
        this.ty === 0
    );
  }

  mult(other) {
    // This is deliberately not isIdentity(). I'm optimizing for the
    // case where there was no preexisting transform at all.
    if (this === identity) { return other; }
    if (other === identity) { return this; }
    return new Transform(
      this.a * other.a + this.c * other.b,
      this.b * other.a + this.d * other.b,
      this.a * other.c + this.c * other.d,
      this.b * other.c + this.d * other.d,
      this.a * other.tx + this.c * other.ty + this.tx,
      this.b * other.tx + this.d * other.ty + this.ty
    );
  }
}

// WARNING: this constant matrix exists as an optimization. But not
// every no-op transform triple-equals this value. If you apply two
// transforms that cancel each other out, you will get an identity
// matrix but it will not triple-equal this one. And that is OK: we
// use the triple-equality as an optimization only, not for
// correctness.
//
// The optimization should be worthwhile because the majority of
// things start out with no preexisting Transform, which we can
// represent as `identity`, which will make identity.mult(something) a
// no-op, etc.
export const identity = new Transform(1, 0, 0, 1, 0, 0);

const matrixPattern = /matrix\((.*)\)/;

function parseTransform(matrixString) {
  let match = matrixPattern.exec(matrixString);
  if (!match) {
    return identity;
  }
  return new Transform(...match[1].split(',').map(parseFloat));
}

function parseOrigin(originString) {
  return originString.split(' ').map(parseFloat);
}

/**
  Returns a Transform instance representing the cumulative CSS
  transform of this element and all its ancestors.

  @function cumulativeTransform
  @hide
  @param {HTMLElement} elt
  @return {Transform}
*/
export function cumulativeTransform(elt) {
  let accumulator = null;
  while (elt && elt.nodeType === 1) {
    let transform = ownTransform(elt);
    if (transform !== identity && !transform.isIdentity()) {
      if (accumulator) {
        accumulator = transform.mult(accumulator);
      } else {
        accumulator = transform;
      }
    }
    elt = elt.parentElement;
  }
  return accumulator || identity;
}

/**
  Returns a Transform instance representing the CSS transform of this
  element.

 * @function ownTransform
 * @param {HTMLElement} elt
 * @return {Transform} instance representing this element's css transform property.
 */
export function ownTransform(elt) {
  let eltStyles = window.getComputedStyle(elt);
  let t = eltStyles.transform !== '' ? eltStyles.transform : elt.style.transform;
  if (t === 'none') {
    // This constant value is an optimization, and we rely on that in
    // cumulativeTransform
    return identity;
  }
  let matrix = parseTransform(t);
  if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) {
    // If there is any rotation, scaling, or skew we need to do it within the context of transform-origin.
    let origin = eltStyles.transformOrigin !== '' ? eltStyles.transformOrigin : elt.style.transformOrigin;
    let [originX, originY] = parseOrigin(origin);
    if (originX === 0 && originY === 0) {
      // transform origin is at 0,0 so it will have no effect, so we're done.
      return matrix;
    }

    return (new Transform(1, 0, 0, 1, originX, originY)).mult(matrix).mult(new Transform(1, 0, 0, 1, -originX, -originY));
  } else {
    // This case is an optimization for when there is only translation.
    return matrix;
  }
}
<|endoftext|>