Skip to content

Commit

Permalink
Fix: default dispatcher doesn't work with jsdom
Browse files Browse the repository at this point in the history
  • Loading branch information
ezhaka authored and qwwdfsad committed Nov 27, 2018
1 parent ca135a2 commit bb0ad4a
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 0 deletions.
22 changes: 22 additions & 0 deletions gradle/test-mocha-js.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,25 @@ task testMochaChrome(type: NodeTask, dependsOn: prepareMochaChrome) {
// todo: Commented out because mocha-headless-chrome does not work on TeamCity
//test.dependsOn testMochaChrome

// -- Testing with Mocha under jsdom

task installDependenciesMochaJsdom(type: NpmTask, dependsOn: [npmInstall]) {
args = ['install',
"mocha@$mocha_version",
'jsdom',
'jsdom-global',
"source-map-support@$source_map_support_version",
'--no-save']
if (project.hasProperty("teamcity")) args += [
"mocha-teamcity-reporter@$mocha_teamcity_reporter_version"]
}

task testMochaJsdom(type: NodeTask, dependsOn: [compileTestKotlin2Js, installDependenciesMochaJsdom]) {
script = file("$node.nodeModulesDir/node_modules/mocha/bin/mocha")
args = [compileTestKotlin2Js.outputFile, '--require', 'source-map-support/register', '--require', 'jsdom-global/register']
if (project.hasProperty("teamcity")) args += ['--reporter', 'mocha-teamcity-reporter']
if (project.hasProperty("mochaTests")) args += ['--grep', "$mochaTests"]
}

test.dependsOn testMochaJsdom

11 changes: 11 additions & 0 deletions js/kotlinx-coroutines-core-js/src/CoroutineContext.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,24 @@ internal actual fun createDefaultDispatcher(): CoroutineDispatcher = when {
// The check for ReactNative is based on https://github.com/facebook/react-native/commit/3c65e62183ce05893be0822da217cb803b121c61
jsTypeOf(navigator) != UNDEFINED && navigator != null && navigator.product == "ReactNative" ->
NodeDispatcher()
// Check if we are running under jsdom. WindowDispatcher doesn't work under jsdom because it accesses MessageEvent#source.
// It is not implemented in jsdom, see https://github.com/jsdom/jsdom/blob/master/Changelog.md
// "It's missing a few semantics, especially around origins, as well as MessageEvent source."
isJsdom() -> NodeDispatcher()
// Check if we are in the browser and must use window.postMessage to avoid setTimeout throttling
jsTypeOf(window) != UNDEFINED && window.asDynamic() != null && jsTypeOf(window.asDynamic().addEventListener) != UNDEFINED ->
window.asCoroutineDispatcher()
// Fallback to NodeDispatcher when browser environment is not detected
else -> NodeDispatcher()
}

private fun isJsdom() = jsTypeOf(navigator) != UNDEFINED &&
navigator != null &&
navigator.userAgent != null &&
jsTypeOf(navigator.userAgent) != UNDEFINED &&
jsTypeOf(navigator.userAgent.match) != UNDEFINED &&
navigator.userAgent.match("\\bjsdom\\b")

internal actual val DefaultDelay: Delay
get() = Dispatchers.Default as Delay

Expand Down

0 comments on commit bb0ad4a

Please sign in to comment.