Skip to content

Async evaluation bug #121

@xogeny

Description

@xogeny

I've created a set of tests to reproduce a problem I've been having with evaluate. This demonstrates that if the input value is a Promise, things work mostly. But one case (involving sorting) seems to somehow deviate from the synchronous case.

Here is the code of the tests (you should be able to just drop it into jsonata-test.js):

const base_input = [
    { uri: "/foo/bar", metadata: { classes: ["foo", "bar"] } },
    { uri: "/bar", metadata: { classes: ["bar"] } },
  ];

describe.only("Bug in async?", () => {
    const asyncEval = (expr, input) => {
        return new Promise((resolve, reject) => {
            expr.evaluate(input, {}, (err, result) => {
                if (err) reject(err);
                else resolve(result);
            })
        })
    }
    it("should return an array synchronously", () => {
        var expr = jsonata("$");
        var result = expr.evaluate(base_input);
        expect(result).to.deep.equal(base_input);
    });
    it("should return a filtered array synchronously", () => {
        var expr = jsonata("$[\"bar\" in metadata.classes]");
        var result = expr.evaluate(base_input);
        expect(result).to.deep.equal([
            { uri: "/foo/bar", metadata: { classes: ["foo", "bar"] } },
            { uri: "/bar", metadata: { classes: ["bar"] } },
          ]);
    });
    it("should return a filtered and sorted array synchronously", () => {
        var expr = jsonata("$[\"bar\" in metadata.classes]^(>uri)");
        var result = expr.evaluate(base_input);
        expect(result).to.deep.equal([
            { uri: "/foo/bar", metadata: { classes: ["foo", "bar"] } },
            { uri: "/bar", metadata: { classes: ["bar"] } },
          ]);
    });
    it("should return an array asynchronously", () => {
        var expr = jsonata("$");
        return asyncEval(expr, base_input)
        .then((result) => {
            expect(result).to.deep.equal(base_input);            
        })
    });
    it("should return a filtered array asynchronously", () => {
        var expr = jsonata("$[\"bar\" in metadata.classes]");
        return asyncEval(expr, Promise.resolve(base_input))
        .then((result) => {
            expect(result).to.deep.equal([
                { uri: "/foo/bar", metadata: { classes: ["foo", "bar"] } },
                { uri: "/bar", metadata: { classes: ["bar"] } },
              ]);            
        })
    });
    it("should return a filtered and sorted array asynchronously", () => {
        var expr = jsonata("$[\"bar\" in metadata.classes]^(uri)");
        return asyncEval(expr, Promise.resolve(base_input))
        .then((result) => {
            expect(result).to.deep.equal([
                { uri: "/foo/bar", metadata: { classes: ["foo", "bar"] } },
                { uri: "/bar", metadata: { classes: ["bar"] } },
              ]);            
        })
    });
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions