Jint: Unexpected Promise.all behavior

Created on 28 May 2021  路  10Comments  路  Source: sebastienros/jint

First of all, thank you very much guys for the new release and the support of promises! Great work!

I am testing promises right now, and run into an issue.

On some occasions, when I do

var evaluationResults = engine.Evaluate("return Promise.all(someArray)").UnwrapIfPromise().ToObject();,

and someArray does not contain any promises at all, but only contains _one_ object, namely a .Net Dictionary<string, object>,

instead of an array with a single element in evaluationResults I get array of KeyValuePair<string, object> of the dictionary within an array.

If instead of an instance of Dictionary<string, object> I put into that array a single simple JS object, it works just as expected.

If I simply add to someArray any additional element, say, true, it works like a charm.

All 10 comments

Thanks for the report, could you please write a failing unit test case for us, would make investigation easier?

Thanks for the report, could you please write a failing unit test case for us, would make investigation easier?

Sure, here it goes.

Hope it helps and thanks for your great work.

@shestakov this is a bit weird, I created baseline based with your test case, but it works?

@shestakov this is a bit weird, I created baseline based with your test case, but it works?

@lahma Sorry I mislead you. I've made some _passing_ tests as an illustration. Replaced them with just one failing test here.

Thanks, #911 should fix this.

@lahma thanks a lot!

I've checked out the workaround you've added.

Could you please explain briefly (if it is possible to explain briefly) why those heuristics (one, two) do exist?

Maybe I could be of more help next time.

These are for the interop as you can call new Array(myClrObject) and it needs to translate to value enumeration at times. Here's a test case for example that hits this path:

public void ArrayFromShouldConvertIEnumerable()
{
    var enumerable = new []
    {
        new Person {Name = "Mike"},
        new Person {Name = "Mika"}
    }.Select(x => x);

    _engine.SetValue("a", enumerable);

    RunTest(@"
        var arr = new Array(a);
        assert(arr.length === 2);
        assert(arr[0].Name === 'Mike');
        assert(arr[1].Name === 'Mika');
    ");

    RunTest(@"
        var arr = Array.from(a);
        assert(arr.length === 2);
        assert(arr[0].Name === 'Mike');
        assert(arr[1].Name === 'Mika');
    ");
}

Generally inside the engine we can skip using the public API that translates things and follows the JS spec when we know what kind of array needs to be produced. CLR interop adds some extra spice to the mix usually and causes some deviation from normal logic / spec.

@lahma looked through ArrayConstructor.Construct. Seems like the bug spotted a deeper problem.

Should IDictionary (which inherits IEnumerable) be ever treated as an array-like object (containing items of type KeyValuePair), or should it always be treated as something object-like and thus always treated in a special way?

Makes sense, I've removed the array-likeness for dictionaries for now, until someone comes up with counter-example why they actually should be array like, oh the interop.

@lahma thank you very much once again!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tricuongle picture tricuongle  路  5Comments

hnafar picture hnafar  路  3Comments

arivera12 picture arivera12  路  35Comments

christianrondeau picture christianrondeau  路  10Comments

Jugolo picture Jugolo  路  13Comments