self-hosted tests work

This commit is contained in:
Dmitry Vasilev
2022-12-25 16:28:06 +08:00
parent fb0bc69328
commit 6fbe67e7f0
3 changed files with 43 additions and 105 deletions

View File

@@ -269,19 +269,13 @@ export const eval_modules = (
// TODO bug if module imported twice, once as external and as regular
patch_promise(globalThis.run_window)
const is_async = has_toplevel_await(parse_result.modules)
const codestring =
`
const codestring = `
let children, prev_children
// TODO refactor, move patch_promise here
globalThis.get_children = () => children
globalThis.set_children = (_children) => children = _children
// TODO use native array for stack for perf?
// TODO use native array for stack for perf? stack contains booleans
const stack = new Array()
let logs = []
@@ -296,6 +290,44 @@ export const eval_modules = (
let is_recording_deferred_calls
let is_toplevel_call = true
let promise_then
function apply_promise_patch() {
promise_then = Promise.prototype.then
Promise.prototype.then = function then(on_resolve, on_reject) {
if(children == null) {
children = []
}
let children_copy = children
const make_callback = cb => cb == null
? null
: value => {
const current = children
children = children_copy
try {
return cb(value)
} finally {
children = current
}
}
return promise_then.call(
this,
make_callback(on_resolve),
make_callback(on_reject),
)
}
}
function remove_promise_patch() {
Promise.prototype.then = promise_then
}
apply_promise_patch()
const set_record_call = () => {
for(let i = 0; i < stack.length; i++) {
stack[i] = true
@@ -634,6 +666,7 @@ export const eval_modules = (
const _logs = logs
logs = []
children = null
remove_promise_patch()
return { modules: __modules, calltree: current_call, logs: _logs }
}
`
@@ -645,6 +678,7 @@ export const eval_modules = (
const _logs = logs
logs = []
children = null
remove_promise_patch()
return { modules: __modules, calltree: current_call, logs: _logs }
}

View File

@@ -1,37 +0,0 @@
export const patch_promise = window => {
if(window.Promise.__patched) {
// already patched
return
}
const _then = window.Promise.prototype.then
window.Promise.prototype.then = function then(on_resolve, on_reject) {
let children = window.get_children()
if(children == null) {
children = []
window.set_children(children)
}
const make_callback = cb => cb == null
? null
: value => {
const current = window.get_children()
window.set_children(children)
try {
return cb(value)
} finally {
window.set_children(current)
}
}
return _then.call(
this,
make_callback(on_resolve),
make_callback(on_reject),
)
}
window.Promise.__patched = true
}

View File

@@ -1,59 +0,0 @@
export const unwrap_settled_promises = calltree => {
let is_finished = false
const unwrap = call => {
// TODO use run_window.Promise
if(!call.ok) {
return
}
if(call.value instanceof Promise) {
call.value
.then(value => {
if(is_finished) {
return
}
call.unwrapped_value = {ok: true, value}
})
.catch(error => {
if(is_finished) {
return
}
call.unwrapped_value = {ok: false, error}
})
}
}
const unwrap_tree = call => {
unwrap(call)
if(call.children != null) {
for(let c of call.children) {
unwrap(c)
}
}
}
unwrap_tree(calltree)
return Promise.resolve().then(() => {
is_finished = true
return calltree
})
}
/*
const delay = new Promise(resolve => setTimeout(() => resolve('123'), 1000))
const tree = {
value: Promise.resolve('resolved'),
ok: true,
children: [
{value: delay, ok: true}
]
}
await unwrap_settled_promises(tree)
console.log('tree', tree)
*/