I know, Chakram is old (no update over a year) but I use it in one of my project because along with Mocha and Chai, it makes a pretty powerful tool for a NodeJS functional testing stack.

For the past few hours, I've been trying to reference a JSON schema from another one stored in the very same directory.

Understanding the documentation about structuring JSON schema is pretty straightforward but in real life, it gets more complicated when you don't fully understand how it really works (and I still don't, don't get me wrong).

The issue

Let's say, I have this schema in entity.json:

{
    "type": "object",
    "properties": {
        "id": {
            "type": "integer",
            "minimum": 1
        },
        "other_entity": {
            "$ref": "other.json#/definitions/schema/other"
        }
    }
}

And next to it, I have the following schema in other.json:

{
    "definitions": {
        "schema": {
            "other": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer",
                        "minimum": 1
                    },
                    "name": {
                        "type": "string"
                    },
                    "datetime": {
                        "type": "string",
                        "format": "date-time"
                    }
                },
                "required": [
                    "id",
                    "name"
                ]
            }
        }
    }
}

Nothing complicated about the schema content, it's rather simple in fact. The doc says that it should work if the file is in the same directory. No need to add an id property, use special URI or absolute path.

Now, the very basic validation code in your Mocha test file. If you are familiar with Chakram, this is how it's done:


it('Returns 201 when entity has been successfully created', function () {
    var fixtures = require(__dirname + '/fixtures/entity').generate();
    var entitySchema = require(__dirname + '/schema/entity.json');

    var response = chakram.post('/entity', fixtures.bodyRequest);

    expect(response).to.have.status(201);
    expect(response).to.have.schema(entitySchema);

    return chakram.wait();
});

When you run the test, it fails because Chakram JSON schema validator is unable to find the JSON schema of entity.json's other_entity property definition. This is very frustrating.

The typical error you get is the following:

 unresolved schemas: ["other.json"]

I tried the following in $ref's value but none of them worked:

./schema/other.json#/definitions/schema/other
../schema/other.json#/definitions/schema/other
/abs/path/schema/other.json#/definitions/schema/other
file:other.json#/definitions/schema/other
file:///abs/path/schema/other.json#/definitions/schema/other

So many attempts while reading JSON schema documentation, GitHub issues and random articles on the internet and still not able to get it working.

Then I started to look into Chakram issues to see if there's something unresolved but no, then I searched hope into Chakram's source code.

I ended up reading Chakram's JSON schema validation library documentation. Truth is, I didn't really know if it was a Chakram issue, a JSON schema format issue, a validation issue or an environment issue.

The answer

When you look at tv4 API, you see this function which has a very appealing name: addSchema(). When I noticed that Chakram exposes this function my hope started to come back:

it('Returns 201 when entity has been successfully created', function () {
    var fixtures = require(__dirname + '/fixtures/entity').generate();
    var entitySchema = require(__dirname + '/schema/entity.json');

    // Registers other.json JSON schema into tv4
    chakram.addSchema('other.json', require(__dirname + '/schema/other.json'));

    var response = chakram.post('/entity', fixtures.bodyRequest);

    expect(response).to.have.status(201);
    expect(response).to.have.schema(entitySchema);

    return chakram.wait();
});

Boom! Test passes. Problem solved, movin' on.

Conclusion: RTFM. Right, but sometimes you don't know which is the right manual to read and that's a bit frustrating to lose so much time...


Joris Berthelot