pulsar/spec/jasmine-test-runner.coffee
Rafael Oleza 7876e04e97 Override global jasmine spec functions
Currently, if a spec uses the global `it` function on an async test,
that test will always pass (since the jasmine version checked in Atom
does not natively support tests that return promises). This can be
confusing since the test behaviour is different between the
async-test-helpers methods and the global ones.

By overriding the global functions, we'll also be able to remove all the
imports from async-test-helpers since they won't be needed anymore.

More info: https://github.com/atom/atom/pull/18896#discussion_r260396102
2019-02-28 15:15:08 +01:00

159 lines
5.1 KiB
CoffeeScript

Grim = require 'grim'
fs = require 'fs-plus'
temp = require 'temp'
path = require 'path'
{ipcRenderer} = require 'electron'
temp.track()
module.exports = ({logFile, headless, testPaths, buildAtomEnvironment}) ->
window[key] = value for key, value of require '../vendor/jasmine'
require 'jasmine-tagged'
# Rewrite global jasmine functions to have support for async tests.
# This way packages can create async specs without having to import these from the
# async-spec-helpers file.
global.it = asyncifyJasmineFn global.it, 1
global.fit = asyncifyJasmineFn global.fit, 1
global.ffit = asyncifyJasmineFn global.ffit, 1
global.fffit = asyncifyJasmineFn global.fffit, 1
global.beforeEach = asyncifyJasmineFn global.beforeEach, 0
global.afterEach = asyncifyJasmineFn global.afterEach, 0
# Allow document.title to be assigned in specs without screwing up spec window title
documentTitle = null
Object.defineProperty document, 'title',
get: -> documentTitle
set: (title) -> documentTitle = title
atomHome = temp.mkdirSync prefix: 'atom-test-home-'
ApplicationDelegate = require '../src/application-delegate'
applicationDelegate = new ApplicationDelegate()
applicationDelegate.setRepresentedFilename = ->
applicationDelegate.setWindowDocumentEdited = ->
window.atom = buildAtomEnvironment({
applicationDelegate, window, document,
configDirPath: atomHome
enablePersistence: false
})
require './spec-helper'
disableFocusMethods() if process.env.JANKY_SHA1 or process.env.CI
requireSpecs(testPath) for testPath in testPaths
setSpecType('user')
resolveWithExitCode = null
promise = new Promise (resolve, reject) -> resolveWithExitCode = resolve
jasmineEnv = jasmine.getEnv()
jasmineEnv.addReporter(buildReporter({logFile, headless, resolveWithExitCode}))
TimeReporter = require './time-reporter'
jasmineEnv.addReporter(new TimeReporter())
if process.env.TEST_JUNIT_XML_PATH
{JasmineJUnitReporter} = require './jasmine-junit-reporter'
process.stdout.write "Outputting JUnit XML to <#{process.env.TEST_JUNIT_XML_PATH}>\n"
outputDir = path.dirname(process.env.TEST_JUNIT_XML_PATH)
fileBase = path.basename(process.env.TEST_JUNIT_XML_PATH, '.xml')
jasmineEnv.addReporter new JasmineJUnitReporter(outputDir, true, false, fileBase, true)
jasmineEnv.setIncludedTags([process.platform])
jasmineContent = document.createElement('div')
jasmineContent.setAttribute('id', 'jasmine-content')
document.body.appendChild(jasmineContent)
jasmineEnv.execute()
promise
asyncifyJasmineFn = (fn, callbackPosition) ->
(args...) ->
if typeof args[callbackPosition] is 'function'
callback = args[callbackPosition]
args[callbackPosition] = (args...) ->
result = callback.apply this, args
if result instanceof Promise
waitsForPromise(-> result)
fn.apply this, args
waitsForPromise = (fn) ->
promise = fn()
global.waitsFor('spec promise to resolve', (done) ->
promise.then(done, (error) ->
jasmine.getEnv().currentSpec.fail error
done()
)
)
disableFocusMethods = ->
['fdescribe', 'ffdescribe', 'fffdescribe', 'fit', 'ffit', 'fffit'].forEach (methodName) ->
focusMethod = window[methodName]
window[methodName] = (description) ->
error = new Error('Focused spec is running on CI')
focusMethod description, -> throw error
requireSpecs = (testPath, specType) ->
if fs.isDirectorySync(testPath)
for testFilePath in fs.listTreeSync(testPath) when /-spec\.(coffee|js)$/.test testFilePath
require(testFilePath)
# Set spec directory on spec for setting up the project in spec-helper
setSpecDirectory(testPath)
else
require(testPath)
setSpecDirectory(path.dirname(testPath))
setSpecField = (name, value) ->
specs = jasmine.getEnv().currentRunner().specs()
return if specs.length is 0
for index in [specs.length-1..0]
break if specs[index][name]?
specs[index][name] = value
setSpecType = (specType) ->
setSpecField('specType', specType)
setSpecDirectory = (specDirectory) ->
setSpecField('specDirectory', specDirectory)
buildReporter = ({logFile, headless, resolveWithExitCode}) ->
if headless
buildTerminalReporter(logFile, resolveWithExitCode)
else
AtomReporter = require './atom-reporter'
reporter = new AtomReporter()
buildTerminalReporter = (logFile, resolveWithExitCode) ->
logStream = fs.openSync(logFile, 'w') if logFile?
log = (str) ->
if logStream?
fs.writeSync(logStream, str)
else
ipcRenderer.send 'write-to-stderr', str
options =
print: (str) ->
log(str)
onComplete: (runner) ->
fs.closeSync(logStream) if logStream?
if Grim.getDeprecationsLength() > 0
Grim.logDeprecations()
resolveWithExitCode(1)
return
if runner.results().failedCount > 0
resolveWithExitCode(1)
else
resolveWithExitCode(0)
if process.env.ATOM_JASMINE_REPORTER is 'list'
{JasmineListReporter} = require './jasmine-list-reporter'
new JasmineListReporter(options)
else
{TerminalReporter} = require 'jasmine-tagged'
new TerminalReporter(options)