test_bundle.js 5.7 KB
Newer Older
W
Winnie Hellmann 已提交
1
/* eslint-disable jasmine/no-global-setup */
2
import $ from 'jquery';
J
Jacob Schatz 已提交
3
import 'vendor/jasmine-jquery';
4
import '~/commons';
F
Fatih Acet 已提交
5

W
Winnie Hellmann 已提交
6 7
import Vue from 'vue';
import VueResource from 'vue-resource';
8
import Translate from '~/vue_shared/translate';
W
Winnie Hellmann 已提交
9

10
import { getDefaultAdapter } from '~/lib/utils/axios_utils';
11 12 13
import { FIXTURES_PATH, TEST_HOST } from './test_constants';

import customMatchers from './matchers';
14

W
winh 已提交
15 16 17 18
const isHeadlessChrome = /\bHeadlessChrome\//.test(navigator.userAgent);
Vue.config.devtools = !isHeadlessChrome;
Vue.config.productionTip = false;

W
Winnie Hellmann 已提交
19 20 21 22 23 24
let hasVueWarnings = false;
Vue.config.warnHandler = (msg, vm, trace) => {
  hasVueWarnings = true;
  fail(`${msg}${trace}`);
};

25
let hasVueErrors = false;
26
Vue.config.errorHandler = function(err) {
27 28 29 30
  hasVueErrors = true;
  fail(err);
};

W
Winnie Hellmann 已提交
31
Vue.use(VueResource);
32
Vue.use(Translate);
W
Winnie Hellmann 已提交
33

34
// enable test fixtures
35 36 37 38
jasmine.getFixtures().fixturesPath = FIXTURES_PATH;
jasmine.getJSONFixtures().fixturesPath = FIXTURES_PATH;

beforeAll(() => jasmine.addMatchers(customMatchers));
39

40 41
// globalize common libraries
window.$ = window.jQuery = $;
42 43

// stub expected globals
44
window.gl = window.gl || {};
45
window.gl.TEST_HOST = TEST_HOST;
46
window.gon = window.gon || {};
M
Mike Greiling 已提交
47
window.gon.test_env = true;
48
gon.relative_url_root = '';
49

50 51
let hasUnhandledPromiseRejections = false;

52
window.addEventListener('unhandledrejection', event => {
53 54 55 56 57
  hasUnhandledPromiseRejections = true;
  console.error('Unhandled promise rejection:');
  console.error(event.reason.stack || event.reason);
});

M
Mike Greiling 已提交
58 59 60 61 62 63
// HACK: Chrome 59 disconnects if there are too many synchronous tests in a row
// because it appears to lock up the thread that communicates to Karma's socket
// This async beforeEach gets called on every spec and releases the JS thread long
// enough for the socket to continue to communicate.
// The downside is that it creates a minor performance penalty in the time it takes
// to run our unit tests.
W
Winnie Hellmann 已提交
64 65 66 67 68 69 70 71
beforeEach(done => done());

const builtinVueHttpInterceptors = Vue.http.interceptors.slice();

beforeEach(() => {
  // restore interceptors so we have no remaining ones from previous tests
  Vue.http.interceptors = builtinVueHttpInterceptors.slice();
});
M
Mike Greiling 已提交
72

73 74
const axiosDefaultAdapter = getDefaultAdapter();

L
Lukas Eipert 已提交
75 76
let testFiles = process.env.TEST_FILES || [];
if (testFiles.length > 0) {
77
  testFiles = testFiles.map(path => path.replace(/^spec\/javascripts\//, '').replace(/\.js$/, ''));
L
Lukas Eipert 已提交
78
  console.log(`Running only tests matching: ${testFiles}`);
79 80
} else {
  console.log('Running all tests');
81 82
}

83 84
// render all of our tests
const testsContext = require.context('.', true, /_spec$/);
85
testsContext.keys().forEach(function(path) {
86
  try {
87
    if (testFiles.length === 0 || testFiles.some(p => path.includes(p))) {
88 89
      testsContext(path);
    }
90
  } catch (err) {
91
    console.error('[ERROR] Unable to load spec: ', path);
92 93
    describe('Test bundle', function() {
      it(`includes '${path}'`, function() {
94 95 96
        expect(err).toBeNull();
      });
    });
97 98
  }
});
99

W
Winnie Hellmann 已提交
100
describe('test errors', () => {
101
  beforeAll(done => {
102
    if (hasUnhandledPromiseRejections || hasVueWarnings || hasVueErrors) {
W
Winnie Hellmann 已提交
103 104 105 106 107 108 109 110 111 112 113 114 115
      setTimeout(done, 1000);
    } else {
      done();
    }
  });

  it('has no unhandled Promise rejections', () => {
    expect(hasUnhandledPromiseRejections).toBe(false);
  });

  it('has no Vue warnings', () => {
    expect(hasVueWarnings).toBe(false);
  });
116 117 118 119

  it('has no Vue error', () => {
    expect(hasVueErrors).toBe(false);
  });
120 121 122 123 124 125

  it('restores axios adapter after mocking', () => {
    if (getDefaultAdapter() !== axiosDefaultAdapter) {
      fail('axios adapter is not restored! Did you forget a restore() on MockAdapter?');
    }
  });
126 127
});

128 129 130 131 132
// if we're generating coverage reports, make sure to include all files so
// that we can catch files with 0% coverage
// see: https://github.com/deepsweet/istanbul-instrumenter-loader/issues/15
if (process.env.BABEL_ENV === 'coverage') {
  // exempt these files from the coverage report
133
  const troubleMakers = [
134
    './blob_edit/blob_bundle.js',
135 136 137
    './boards/components/modal/empty_state.js',
    './boards/components/modal/footer.js',
    './boards/components/modal/header.js',
138
    './cycle_analytics/cycle_analytics_bundle.js',
139 140 141
    './cycle_analytics/components/stage_plan_component.js',
    './cycle_analytics/components/stage_staging_component.js',
    './cycle_analytics/components/stage_test_component.js',
142 143
    './commit/pipelines/pipelines_bundle.js',
    './diff_notes/diff_notes_bundle.js',
144 145
    './diff_notes/components/jump_to_discussion.js',
    './diff_notes/components/resolve_count.js',
146 147 148 149 150 151
    './dispatcher.js',
    './environments/environments_bundle.js',
    './graphs/graphs_bundle.js',
    './issuable/time_tracking/time_tracking_bundle.js',
    './main.js',
    './merge_conflicts/merge_conflicts_bundle.js',
152 153
    './merge_conflicts/components/inline_conflict_lines.js',
    './merge_conflicts/components/parallel_conflict_lines.js',
154 155
    './monitoring/monitoring_bundle.js',
    './network/network_bundle.js',
156
    './network/branch_graph.js',
157 158 159 160 161
    './profile/profile_bundle.js',
    './protected_branches/protected_branches_bundle.js',
    './snippet/snippet_bundle.js',
    './terminal/terminal_bundle.js',
    './users/users_bundle.js',
R
Regis Boudinot 已提交
162
    './issue_show/index.js',
163 164
  ];

165
  describe('Uncovered files', function() {
166
    const sourceFiles = require.context('~', true, /\.js$/);
J
Jacob Schatz 已提交
167 168 169

    $.holdReady(true);

170
    sourceFiles.keys().forEach(function(path) {
171 172 173 174
      // ignore if there is a matching spec file
      if (testsContext.keys().indexOf(`${path.replace(/\.js$/, '')}_spec`) > -1) {
        return;
      }
175

176
      it(`includes '${path}'`, function() {
177 178 179 180 181 182
        try {
          sourceFiles(path);
        } catch (err) {
          if (troubleMakers.indexOf(path) === -1) {
            expect(err).toBeNull();
          }
183
        }
184
      });
185 186
    });
  });
187
}