[6a3a178] | 1 | (function(window) {
|
---|
| 2 |
|
---|
| 3 | /* eslint no-unused-vars: ["error", { "varsIgnorePattern": "(createSpecFilter|createStartFn)" }] */
|
---|
| 4 |
|
---|
| 5 | 'use strict'
|
---|
| 6 |
|
---|
| 7 | // Save link to native Date object
|
---|
| 8 | // before it might be mocked by the user
|
---|
| 9 | var _Date = Date
|
---|
| 10 |
|
---|
| 11 | /**
|
---|
| 12 | * Decision maker for whether a stack entry is considered external to jasmine and karma.
|
---|
| 13 | * @param {String} entry Error stack entry.
|
---|
| 14 | * @return {Boolean} True if external, False otherwise.
|
---|
| 15 | */
|
---|
| 16 | function isExternalStackEntry (entry) {
|
---|
| 17 | return !!entry &&
|
---|
| 18 | // entries related to jasmine and karma-jasmine:
|
---|
| 19 | !/\/(jasmine-core|karma-jasmine)\//.test(entry) &&
|
---|
| 20 | // karma specifics, e.g. "at http://localhost:7018/karma.js:185"
|
---|
| 21 | !/\/(karma.js|context.html):/.test(entry)
|
---|
| 22 | }
|
---|
| 23 |
|
---|
| 24 | /**
|
---|
| 25 | * Returns relevant stack entries.
|
---|
| 26 | * @param {Array} stack frames
|
---|
| 27 | * @return {Array} A list of relevant stack entries.
|
---|
| 28 | */
|
---|
| 29 | function getRelevantStackFrom (stack) {
|
---|
| 30 | var filteredStack = []
|
---|
| 31 | var relevantStack = []
|
---|
| 32 |
|
---|
| 33 | for (var i = 0; i < stack.length; i += 1) {
|
---|
| 34 | if (isExternalStackEntry(stack[i])) {
|
---|
| 35 | filteredStack.push(stack[i])
|
---|
| 36 | }
|
---|
| 37 | }
|
---|
| 38 |
|
---|
| 39 | // If the filtered stack is empty, i.e. the error originated entirely from within jasmine or karma, then the whole stack
|
---|
| 40 | // should be relevant.
|
---|
| 41 | if (filteredStack.length === 0) {
|
---|
| 42 | filteredStack = stack
|
---|
| 43 | }
|
---|
| 44 |
|
---|
| 45 | for (i = 0; i < filteredStack.length; i += 1) {
|
---|
| 46 | if (filteredStack[i]) {
|
---|
| 47 | relevantStack.push(filteredStack[i])
|
---|
| 48 | }
|
---|
| 49 | }
|
---|
| 50 |
|
---|
| 51 | return relevantStack
|
---|
| 52 | }
|
---|
| 53 |
|
---|
| 54 | /**
|
---|
| 55 | * Custom formatter for a failed step.
|
---|
| 56 | *
|
---|
| 57 | * Different browsers report stack trace in different ways. This function
|
---|
| 58 | * attempts to provide a concise, relevant error message by removing the
|
---|
| 59 | * unnecessary stack traces coming from the testing framework itself as well
|
---|
| 60 | * as possible repetition.
|
---|
| 61 | *
|
---|
| 62 | * @see https://github.com/karma-runner/karma-jasmine/issues/60
|
---|
| 63 | * @param {Object} step Step object with stack and message properties.
|
---|
| 64 | * @return {String} Formatted step.
|
---|
| 65 | */
|
---|
| 66 | function formatFailedStep (step) {
|
---|
| 67 | var relevantMessage = []
|
---|
| 68 | var relevantStack = []
|
---|
| 69 |
|
---|
| 70 | // Safari/Firefox seems to have no stack trace,
|
---|
| 71 | // so we just return the error message and if available
|
---|
| 72 | // construct a stacktrace out of filename and lineno:
|
---|
| 73 | if (!step.stack) {
|
---|
| 74 | if (step.filename) {
|
---|
| 75 | var stackframe = step.filename
|
---|
| 76 | if (step.lineno) {
|
---|
| 77 | stackframe = stackframe + ':' + step.lineno
|
---|
| 78 | }
|
---|
| 79 | relevantStack.push(stackframe)
|
---|
| 80 | }
|
---|
| 81 | relevantMessage.push(step.message)
|
---|
| 82 | return relevantMessage.concat(relevantStack).join('\n')
|
---|
| 83 | }
|
---|
| 84 |
|
---|
| 85 | // Remove the message prior to processing the stack to prevent issues like
|
---|
| 86 | // https://github.com/karma-runner/karma-jasmine/issues/79
|
---|
| 87 | var stackframes = step.stack.split('\n')
|
---|
| 88 | var messageOnStack = null
|
---|
| 89 | if (stackframes[0].indexOf(step.message) !== -1) {
|
---|
| 90 | // Remove the message if it is in the stack string (eg Chrome)
|
---|
| 91 | messageOnStack = stackframes.shift()
|
---|
| 92 | }
|
---|
| 93 | // Filter frames
|
---|
| 94 | var relevantStackFrames = getRelevantStackFrom(stackframes)
|
---|
| 95 | if (messageOnStack) {
|
---|
| 96 | // Put the message back if we removed it.
|
---|
| 97 | relevantStackFrames.unshift(messageOnStack)
|
---|
| 98 | } else {
|
---|
| 99 | // The stack did not have the step.message so add it.
|
---|
| 100 | relevantStackFrames.unshift(step.message)
|
---|
| 101 | }
|
---|
| 102 |
|
---|
| 103 | return relevantStackFrames.join('\n')
|
---|
| 104 | }
|
---|
| 105 |
|
---|
| 106 | function debugUrl (description) {
|
---|
| 107 | // A link to re-run just one failed test case.
|
---|
| 108 | return window.location.origin + '/debug.html?spec=' + encodeURIComponent(description)
|
---|
| 109 | }
|
---|
| 110 |
|
---|
| 111 | function SuiteNode (name, parent) {
|
---|
| 112 | this.name = name
|
---|
| 113 | this.parent = parent
|
---|
| 114 | this.children = []
|
---|
| 115 |
|
---|
| 116 | this.addChild = function (name) {
|
---|
| 117 | var suite = new SuiteNode(name, this)
|
---|
| 118 | this.children.push(suite)
|
---|
| 119 | return suite
|
---|
| 120 | }
|
---|
| 121 | }
|
---|
| 122 |
|
---|
| 123 | function processSuite (suite, pointer) {
|
---|
| 124 | var child
|
---|
| 125 | var childPointer
|
---|
| 126 |
|
---|
| 127 | for (var i = 0; i < suite.children.length; i++) {
|
---|
| 128 | child = suite.children[i]
|
---|
| 129 |
|
---|
| 130 | if (child.children) {
|
---|
| 131 | childPointer = pointer[child.description] = { _: [] }
|
---|
| 132 | processSuite(child, childPointer)
|
---|
| 133 | } else {
|
---|
| 134 | if (!pointer._) {
|
---|
| 135 | pointer._ = []
|
---|
| 136 | }
|
---|
| 137 | pointer._.push(child.description)
|
---|
| 138 | }
|
---|
| 139 | }
|
---|
| 140 | }
|
---|
| 141 |
|
---|
| 142 | function getAllSpecNames (topSuite) {
|
---|
| 143 | var specNames = {}
|
---|
| 144 |
|
---|
| 145 | processSuite(topSuite, specNames)
|
---|
| 146 |
|
---|
| 147 | return specNames
|
---|
| 148 | }
|
---|
| 149 |
|
---|
| 150 | /**
|
---|
| 151 | * Very simple reporter for Jasmine.
|
---|
| 152 | */
|
---|
| 153 | function KarmaReporter (tc, jasmineEnv) {
|
---|
| 154 | var currentSuite = new SuiteNode()
|
---|
| 155 |
|
---|
| 156 | var startTimeCurrentSpec = new _Date().getTime()
|
---|
| 157 |
|
---|
| 158 | function handleGlobalErrors (result) {
|
---|
| 159 | if (result.failedExpectations && result.failedExpectations.length) {
|
---|
| 160 | var message = 'An error was thrown in afterAll'
|
---|
| 161 | var steps = result.failedExpectations
|
---|
| 162 | for (var i = 0, l = steps.length; i < l; i++) {
|
---|
| 163 | message += '\n' + formatFailedStep(steps[i])
|
---|
| 164 | }
|
---|
| 165 |
|
---|
| 166 | tc.error(message)
|
---|
| 167 | }
|
---|
| 168 | }
|
---|
| 169 |
|
---|
| 170 | /**
|
---|
| 171 | * Jasmine 2.0 dispatches the following events:
|
---|
| 172 | *
|
---|
| 173 | * - jasmineStarted
|
---|
| 174 | * - jasmineDone
|
---|
| 175 | * - suiteStarted
|
---|
| 176 | * - suiteDone
|
---|
| 177 | * - specStarted
|
---|
| 178 | * - specDone
|
---|
| 179 | */
|
---|
| 180 |
|
---|
| 181 | this.jasmineStarted = function (data) {
|
---|
| 182 | // TODO(vojta): Do not send spec names when polling.
|
---|
| 183 | tc.info({
|
---|
| 184 | event: 'jasmineStarted',
|
---|
| 185 | total: data.totalSpecsDefined,
|
---|
| 186 | specs: getAllSpecNames(jasmineEnv.topSuite())
|
---|
| 187 | })
|
---|
| 188 | }
|
---|
| 189 |
|
---|
| 190 | this.jasmineDone = function (result) {
|
---|
| 191 | result = result || {}
|
---|
| 192 |
|
---|
| 193 | // Any errors in top-level afterAll blocks are given here.
|
---|
| 194 | handleGlobalErrors(result)
|
---|
| 195 |
|
---|
| 196 | // Remove functions from called back results to avoid IPC errors in Electron
|
---|
| 197 | // https://github.com/twolfson/karma-electron/issues/47
|
---|
| 198 | var cleanedOrder
|
---|
| 199 | if (result.order) {
|
---|
| 200 | cleanedOrder = {}
|
---|
| 201 | var orderKeys = Object.getOwnPropertyNames(result.order)
|
---|
| 202 | for (var i = 0; i < orderKeys.length; i++) {
|
---|
| 203 | var orderKey = orderKeys[i]
|
---|
| 204 | if (typeof result.order[orderKey] !== 'function') {
|
---|
| 205 | cleanedOrder[orderKey] = result.order[orderKey]
|
---|
| 206 | }
|
---|
| 207 | }
|
---|
| 208 | }
|
---|
| 209 |
|
---|
| 210 | tc.complete({
|
---|
| 211 | order: cleanedOrder,
|
---|
| 212 | coverage: window.__coverage__
|
---|
| 213 | })
|
---|
| 214 | }
|
---|
| 215 |
|
---|
| 216 | this.suiteStarted = function (result) {
|
---|
| 217 | currentSuite = currentSuite.addChild(result.description)
|
---|
| 218 | tc.info({
|
---|
| 219 | event: 'suiteStarted',
|
---|
| 220 | result: result
|
---|
| 221 | })
|
---|
| 222 | }
|
---|
| 223 |
|
---|
| 224 | this.suiteDone = function (result) {
|
---|
| 225 | // In the case of xdescribe, only "suiteDone" is fired.
|
---|
| 226 | // We need to skip that.
|
---|
| 227 | if (result.description !== currentSuite.name) {
|
---|
| 228 | return
|
---|
| 229 | }
|
---|
| 230 |
|
---|
| 231 | // Any errors in afterAll blocks are given here, except for top-level
|
---|
| 232 | // afterAll blocks.
|
---|
| 233 | handleGlobalErrors(result)
|
---|
| 234 |
|
---|
| 235 | currentSuite = currentSuite.parent
|
---|
| 236 |
|
---|
| 237 | tc.info({
|
---|
| 238 | event: 'suiteDone',
|
---|
| 239 | result: result
|
---|
| 240 | })
|
---|
| 241 | }
|
---|
| 242 |
|
---|
| 243 | this.specStarted = function () {
|
---|
| 244 | startTimeCurrentSpec = new _Date().getTime()
|
---|
| 245 | }
|
---|
| 246 |
|
---|
| 247 | this.specDone = function (specResult) {
|
---|
| 248 | var skipped = specResult.status === 'disabled' || specResult.status === 'pending' || specResult.status === 'excluded'
|
---|
| 249 | var result = {
|
---|
| 250 | fullName: specResult.fullName,
|
---|
| 251 | description: specResult.description,
|
---|
| 252 | id: specResult.id,
|
---|
| 253 | log: [],
|
---|
| 254 | skipped: skipped,
|
---|
| 255 | disabled: specResult.status === 'disabled' || specResult.status === 'excluded',
|
---|
| 256 | pending: specResult.status === 'pending',
|
---|
| 257 | success: specResult.failedExpectations.length === 0,
|
---|
| 258 | suite: [],
|
---|
| 259 | time: skipped ? 0 : new _Date().getTime() - startTimeCurrentSpec,
|
---|
| 260 | executedExpectationsCount: specResult.failedExpectations.length + specResult.passedExpectations.length,
|
---|
| 261 | passedExpectations: specResult.passedExpectations,
|
---|
| 262 | properties: specResult.properties
|
---|
| 263 | }
|
---|
| 264 |
|
---|
| 265 | // generate ordered list of (nested) suite names
|
---|
| 266 | var suitePointer = currentSuite
|
---|
| 267 | while (suitePointer.parent) {
|
---|
| 268 | result.suite.unshift(suitePointer.name)
|
---|
| 269 | suitePointer = suitePointer.parent
|
---|
| 270 | }
|
---|
| 271 |
|
---|
| 272 | if (!result.success) {
|
---|
| 273 | var steps = specResult.failedExpectations
|
---|
| 274 | for (var i = 0, l = steps.length; i < l; i++) {
|
---|
| 275 | result.log.push(formatFailedStep(steps[i]))
|
---|
| 276 | }
|
---|
| 277 |
|
---|
| 278 | if (typeof window !== 'undefined' && window.location && window.location.origin) {
|
---|
| 279 | // Report the name of fhe failing spec so the reporter can emit a debug url.
|
---|
| 280 | result.debug_url = debugUrl(specResult.fullName)
|
---|
| 281 | }
|
---|
| 282 | }
|
---|
| 283 |
|
---|
| 284 | // When failSpecWithNoExpectations is true, Jasmine will report specs without expectations as failed
|
---|
| 285 | if (result.executedExpectationsCount === 0 && specResult.status === 'failed') {
|
---|
| 286 | result.success = false
|
---|
| 287 | result.log.push('Spec has no expectations')
|
---|
| 288 | }
|
---|
| 289 |
|
---|
| 290 | tc.result(result)
|
---|
| 291 | delete specResult.startTime
|
---|
| 292 | }
|
---|
| 293 | }
|
---|
| 294 |
|
---|
| 295 | /**
|
---|
| 296 | * Extract grep option from karma config
|
---|
| 297 | * @param {[Array|string]} clientArguments The karma client arguments
|
---|
| 298 | * @return {string} The value of grep option by default empty string
|
---|
| 299 | */
|
---|
| 300 | var getGrepOption = function (clientArguments) {
|
---|
| 301 | var grepRegex = /^--grep=(.*)$/
|
---|
| 302 |
|
---|
| 303 | if (Object.prototype.toString.call(clientArguments) === '[object Array]') {
|
---|
| 304 | var indexOfGrep = indexOf(clientArguments, '--grep')
|
---|
| 305 |
|
---|
| 306 | if (indexOfGrep !== -1) {
|
---|
| 307 | return clientArguments[indexOfGrep + 1]
|
---|
| 308 | }
|
---|
| 309 |
|
---|
| 310 | return map(filter(clientArguments, function (arg) {
|
---|
| 311 | return grepRegex.test(arg)
|
---|
| 312 | }), function (arg) {
|
---|
| 313 | return arg.replace(grepRegex, '$1')
|
---|
| 314 | })[0] || ''
|
---|
| 315 | } else if (typeof clientArguments === 'string') {
|
---|
| 316 | var match = /--grep=([^=]+)/.exec(clientArguments)
|
---|
| 317 |
|
---|
| 318 | return match ? match[1] : ''
|
---|
| 319 | }
|
---|
| 320 | }
|
---|
| 321 |
|
---|
| 322 | var createRegExp = function (filter) {
|
---|
| 323 | filter = filter || ''
|
---|
| 324 | if (filter === '') {
|
---|
| 325 | return new RegExp() // to match all
|
---|
| 326 | }
|
---|
| 327 |
|
---|
| 328 | var regExp = /^[/](.*)[/]([gmixXsuUAJD]*)$/ // pattern to check whether the string is RegExp pattern
|
---|
| 329 |
|
---|
| 330 | var parts = regExp.exec(filter)
|
---|
| 331 | if (parts === null) {
|
---|
| 332 | return new RegExp(filter.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')) // escape functional symbols
|
---|
| 333 | }
|
---|
| 334 |
|
---|
| 335 | var patternExpression = parts[1]
|
---|
| 336 | var patternSwitches = parts[2]
|
---|
| 337 | return new RegExp(patternExpression, patternSwitches)
|
---|
| 338 | }
|
---|
| 339 |
|
---|
| 340 | function getGrepSpecsToRun (clientConfig, specs) {
|
---|
| 341 | var grepOption = getGrepOption(clientConfig.args)
|
---|
| 342 | if (grepOption) {
|
---|
| 343 | var regExp = createRegExp(grepOption)
|
---|
| 344 | return filter(specs, function specFilter (spec) {
|
---|
| 345 | return regExp.test(spec.getFullName())
|
---|
| 346 | })
|
---|
| 347 | }
|
---|
| 348 | }
|
---|
| 349 |
|
---|
| 350 | function parseQueryParams (location) {
|
---|
| 351 | var params = {}
|
---|
| 352 | if (location && Object.prototype.hasOwnProperty.call(location, 'search')) {
|
---|
| 353 | var pairs = location.search.substr(1).split('&')
|
---|
| 354 | for (var i = 0; i < pairs.length; i++) {
|
---|
| 355 | var keyValue = pairs[i].split('=')
|
---|
| 356 | params[decodeURIComponent(keyValue[0])] =
|
---|
| 357 | decodeURIComponent(keyValue[1])
|
---|
| 358 | }
|
---|
| 359 | }
|
---|
| 360 | return params
|
---|
| 361 | }
|
---|
| 362 |
|
---|
| 363 | function getId (s) {
|
---|
| 364 | return s.id
|
---|
| 365 | }
|
---|
| 366 |
|
---|
| 367 | function getSpecsByName (specs, name) {
|
---|
| 368 | specs = specs.filter(function (s) {
|
---|
| 369 | return s.name.indexOf(name) !== -1
|
---|
| 370 | })
|
---|
| 371 | if (specs.length === 0) {
|
---|
| 372 | throw new Error('No spec found with name: "' + name + '"')
|
---|
| 373 | }
|
---|
| 374 | return specs
|
---|
| 375 | }
|
---|
| 376 |
|
---|
| 377 | function getDebugSpecToRun (location, specs) {
|
---|
| 378 | var queryParams = parseQueryParams(location)
|
---|
| 379 | var spec = queryParams.spec
|
---|
| 380 | if (spec) {
|
---|
| 381 | // A single spec has been requested by name for debugging.
|
---|
| 382 | return getSpecsByName(specs, spec)
|
---|
| 383 | }
|
---|
| 384 | }
|
---|
| 385 |
|
---|
| 386 | function getSpecsToRunForCurrentShard (specs, shardIndex, totalShards) {
|
---|
| 387 | if (specs.length < totalShards) {
|
---|
| 388 | throw new Error(
|
---|
| 389 | 'More shards (' + totalShards + ') than test specs (' + specs.length +
|
---|
| 390 | ')')
|
---|
| 391 | }
|
---|
| 392 |
|
---|
| 393 | // Just do a simple sharding strategy of dividing the number of specs
|
---|
| 394 | // equally.
|
---|
| 395 | var firstSpec = Math.floor(specs.length * shardIndex / totalShards)
|
---|
| 396 | var lastSpec = Math.floor(specs.length * (shardIndex + 1) / totalShards)
|
---|
| 397 | return specs.slice(firstSpec, lastSpec)
|
---|
| 398 | }
|
---|
| 399 |
|
---|
| 400 | function getShardedSpecsToRun (specs, clientConfig) {
|
---|
| 401 | var shardIndex = clientConfig.shardIndex
|
---|
| 402 | var totalShards = clientConfig.totalShards
|
---|
| 403 | if (shardIndex != null && totalShards != null) {
|
---|
| 404 | // Sharded mode - Run only the subset of the specs corresponding to the
|
---|
| 405 | // current shard.
|
---|
| 406 | return getSpecsToRunForCurrentShard(
|
---|
| 407 | specs, Number(shardIndex), Number(totalShards))
|
---|
| 408 | }
|
---|
| 409 | }
|
---|
| 410 |
|
---|
| 411 | /**
|
---|
| 412 | * Create jasmine spec filter
|
---|
| 413 | * @param {Object} clientConfig karma config
|
---|
| 414 | * @param {!Object} jasmineEnv
|
---|
| 415 | */
|
---|
| 416 | var KarmaSpecFilter = function (clientConfig, jasmineEnv) {
|
---|
| 417 | /**
|
---|
| 418 | * Walk the test suite tree depth first and collect all test specs
|
---|
| 419 | * @param {!Object} jasmineEnv
|
---|
| 420 | * @return {!Array<string>} All possible tests.
|
---|
| 421 | */
|
---|
| 422 | function getAllSpecs (jasmineEnv) {
|
---|
| 423 | var specs = []
|
---|
| 424 | var stack = [jasmineEnv.topSuite()]
|
---|
| 425 | var currentNode
|
---|
| 426 | while ((currentNode = stack.pop())) {
|
---|
| 427 | if (currentNode.children) {
|
---|
| 428 | // jasmine.Suite
|
---|
| 429 | stack = stack.concat(currentNode.children)
|
---|
| 430 | } else if (currentNode.id) {
|
---|
| 431 | // jasmine.Spec
|
---|
| 432 | specs.unshift(currentNode)
|
---|
| 433 | }
|
---|
| 434 | }
|
---|
| 435 |
|
---|
| 436 | return specs
|
---|
| 437 | }
|
---|
| 438 |
|
---|
| 439 | /**
|
---|
| 440 | * Filter the specs with URL search params and config.
|
---|
| 441 | * @param {!Object} location property 'search' from URL.
|
---|
| 442 | * @param {!Object} clientConfig karma client config
|
---|
| 443 | * @param {!Object} jasmineEnv
|
---|
| 444 | * @return {!Array<string>}
|
---|
| 445 | */
|
---|
| 446 | function getSpecsToRun (location, clientConfig, jasmineEnv) {
|
---|
| 447 | var specs = getAllSpecs(jasmineEnv).map(function (spec) {
|
---|
| 448 | spec.name = spec.getFullName()
|
---|
| 449 | return spec
|
---|
| 450 | })
|
---|
| 451 |
|
---|
| 452 | if (!specs || !specs.length) {
|
---|
| 453 | return []
|
---|
| 454 | }
|
---|
| 455 |
|
---|
| 456 | return getGrepSpecsToRun(clientConfig, specs) ||
|
---|
| 457 | getDebugSpecToRun(location, specs) ||
|
---|
| 458 | getShardedSpecsToRun(specs, clientConfig) ||
|
---|
| 459 | specs
|
---|
| 460 | }
|
---|
| 461 |
|
---|
| 462 | this.specIdsToRun =
|
---|
| 463 | getSpecsToRun(window.location, clientConfig, jasmineEnv).map(getId)
|
---|
| 464 |
|
---|
| 465 | this.matches = function (spec) {
|
---|
| 466 | return this.specIdsToRun.indexOf(spec.id) !== -1
|
---|
| 467 | }
|
---|
| 468 | }
|
---|
| 469 |
|
---|
| 470 | /**
|
---|
| 471 | * Configure jasmine specFilter
|
---|
| 472 | *
|
---|
| 473 | * This function is invoked from the wrapper.
|
---|
| 474 | * @see adapter.wrapper
|
---|
| 475 | *
|
---|
| 476 | * @param {Object} config The karma config
|
---|
| 477 | * @param {Object} jasmineEnv jasmine environment object
|
---|
| 478 | */
|
---|
| 479 | var createSpecFilter = function (config, jasmineEnv) {
|
---|
| 480 | var karmaSpecFilter = new KarmaSpecFilter(config, jasmineEnv)
|
---|
| 481 |
|
---|
| 482 | var specFilter = function (spec) {
|
---|
| 483 | return karmaSpecFilter.matches(spec)
|
---|
| 484 | }
|
---|
| 485 |
|
---|
| 486 | return specFilter
|
---|
| 487 | }
|
---|
| 488 |
|
---|
| 489 | /**
|
---|
| 490 | * Karma starter function factory.
|
---|
| 491 | *
|
---|
| 492 | * This function is invoked from the wrapper.
|
---|
| 493 | * @see adapter.wrapper
|
---|
| 494 | *
|
---|
| 495 | * @param {Object} karma Karma runner instance.
|
---|
| 496 | * @param {Object} [jasmineEnv] Optional Jasmine environment for testing.
|
---|
| 497 | * @return {Function} Karma starter function.
|
---|
| 498 | */
|
---|
| 499 | function createStartFn (karma, jasmineEnv) {
|
---|
| 500 | // This function will be assigned to `window.__karma__.start`:
|
---|
| 501 | return function () {
|
---|
| 502 | var clientConfig = karma.config || {}
|
---|
| 503 | var jasmineConfig = clientConfig.jasmine || {}
|
---|
| 504 |
|
---|
| 505 | jasmineEnv = jasmineEnv || window.jasmine.getEnv()
|
---|
| 506 |
|
---|
| 507 | jasmineConfig.specFilter = createSpecFilter(clientConfig, jasmineEnv)
|
---|
| 508 |
|
---|
| 509 | jasmineEnv.configure(jasmineConfig)
|
---|
| 510 |
|
---|
| 511 | window.jasmine.DEFAULT_TIMEOUT_INTERVAL = jasmineConfig.timeoutInterval ||
|
---|
| 512 | window.jasmine.DEFAULT_TIMEOUT_INTERVAL
|
---|
| 513 | jasmineEnv.addReporter(new KarmaReporter(karma, jasmineEnv))
|
---|
| 514 | jasmineEnv.execute()
|
---|
| 515 | }
|
---|
| 516 | }
|
---|
| 517 |
|
---|
| 518 | function indexOf (collection, find, i /* opt */) {
|
---|
| 519 | if (collection.indexOf) {
|
---|
| 520 | return collection.indexOf(find, i)
|
---|
| 521 | }
|
---|
| 522 |
|
---|
| 523 | if (i === undefined) { i = 0 }
|
---|
| 524 | if (i < 0) { i += collection.length }
|
---|
| 525 | if (i < 0) { i = 0 }
|
---|
| 526 | for (var n = collection.length; i < n; i++) {
|
---|
| 527 | if (i in collection && collection[i] === find) {
|
---|
| 528 | return i
|
---|
| 529 | }
|
---|
| 530 | }
|
---|
| 531 | return -1
|
---|
| 532 | }
|
---|
| 533 |
|
---|
| 534 | function filter (collection, filter, that /* opt */) {
|
---|
| 535 | if (collection.filter) {
|
---|
| 536 | return collection.filter(filter, that)
|
---|
| 537 | }
|
---|
| 538 |
|
---|
| 539 | var other = []
|
---|
| 540 | var v
|
---|
| 541 | for (var i = 0, n = collection.length; i < n; i++) {
|
---|
| 542 | if (i in collection && filter.call(that, v = collection[i], i, collection)) {
|
---|
| 543 | other.push(v)
|
---|
| 544 | }
|
---|
| 545 | }
|
---|
| 546 | return other
|
---|
| 547 | }
|
---|
| 548 |
|
---|
| 549 | function map (collection, mapper, that /* opt */) {
|
---|
| 550 | if (collection.map) {
|
---|
| 551 | return collection.map(mapper, that)
|
---|
| 552 | }
|
---|
| 553 |
|
---|
| 554 | var other = new Array(collection.length)
|
---|
| 555 | for (var i = 0, n = collection.length; i < n; i++) {
|
---|
| 556 | if (i in collection) {
|
---|
| 557 | other[i] = mapper.call(that, collection[i], i, collection)
|
---|
| 558 | }
|
---|
| 559 | }
|
---|
| 560 | return other
|
---|
| 561 | }
|
---|
| 562 |
|
---|
| 563 | window.__karma__.start = createStartFn(window.__karma__)
|
---|
| 564 |
|
---|
| 565 | })(typeof window !== 'undefined' ? window : global);
|
---|