Skip to content

Commit bb0ad4a

Browse files
ezhakaqwwdfsad
authored andcommitted
Fix: default dispatcher doesn't work with jsdom
1 parent ca135a2 commit bb0ad4a

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

gradle/test-mocha-js.gradle

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,25 @@ task testMochaChrome(type: NodeTask, dependsOn: prepareMochaChrome) {
7474
// todo: Commented out because mocha-headless-chrome does not work on TeamCity
7575
//test.dependsOn testMochaChrome
7676

77+
// -- Testing with Mocha under jsdom
78+
79+
task installDependenciesMochaJsdom(type: NpmTask, dependsOn: [npmInstall]) {
80+
args = ['install',
81+
"mocha@$mocha_version",
82+
'jsdom',
83+
'jsdom-global',
84+
"source-map-support@$source_map_support_version",
85+
'--no-save']
86+
if (project.hasProperty("teamcity")) args += [
87+
"mocha-teamcity-reporter@$mocha_teamcity_reporter_version"]
88+
}
89+
90+
task testMochaJsdom(type: NodeTask, dependsOn: [compileTestKotlin2Js, installDependenciesMochaJsdom]) {
91+
script = file("$node.nodeModulesDir/node_modules/mocha/bin/mocha")
92+
args = [compileTestKotlin2Js.outputFile, '--require', 'source-map-support/register', '--require', 'jsdom-global/register']
93+
if (project.hasProperty("teamcity")) args += ['--reporter', 'mocha-teamcity-reporter']
94+
if (project.hasProperty("mochaTests")) args += ['--grep', "$mochaTests"]
95+
}
96+
97+
test.dependsOn testMochaJsdom
98+

js/kotlinx-coroutines-core-js/src/CoroutineContext.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,24 @@ internal actual fun createDefaultDispatcher(): CoroutineDispatcher = when {
1717
// The check for ReactNative is based on https://github.com/facebook/react-native/commit/3c65e62183ce05893be0822da217cb803b121c61
1818
jsTypeOf(navigator) != UNDEFINED && navigator != null && navigator.product == "ReactNative" ->
1919
NodeDispatcher()
20+
// Check if we are running under jsdom. WindowDispatcher doesn't work under jsdom because it accesses MessageEvent#source.
21+
// It is not implemented in jsdom, see https://github.com/jsdom/jsdom/blob/master/Changelog.md
22+
// "It's missing a few semantics, especially around origins, as well as MessageEvent source."
23+
isJsdom() -> NodeDispatcher()
2024
// Check if we are in the browser and must use window.postMessage to avoid setTimeout throttling
2125
jsTypeOf(window) != UNDEFINED && window.asDynamic() != null && jsTypeOf(window.asDynamic().addEventListener) != UNDEFINED ->
2226
window.asCoroutineDispatcher()
2327
// Fallback to NodeDispatcher when browser environment is not detected
2428
else -> NodeDispatcher()
2529
}
2630

31+
private fun isJsdom() = jsTypeOf(navigator) != UNDEFINED &&
32+
navigator != null &&
33+
navigator.userAgent != null &&
34+
jsTypeOf(navigator.userAgent) != UNDEFINED &&
35+
jsTypeOf(navigator.userAgent.match) != UNDEFINED &&
36+
navigator.userAgent.match("\\bjsdom\\b")
37+
2738
internal actual val DefaultDelay: Delay
2839
get() = Dispatchers.Default as Delay
2940

0 commit comments

Comments
 (0)