Dodomac
Dodomac

Reputation: 303

Can JSON integer attributes be referenced?

I have the following JSON schema that I want to validate and Python unittest.

{
    "properties": {

        "traffic_parameters" {

            "capacity": {

                "oneOf": [
                    {
                        "max_percentage": {

                            "type": "integer",
                            "minimum" : 1,
                            "maximum" : 150
                        },

                        "min_percentage": {

                            "type": "integer",
                            "minimum" : 1,
                            "maximum" : {

                                "$ref": "#/properties/traffic_parameters/capacity/oneOf/max_percentage/minimum"
                            }
                        }
                    },

                    {
                        "percentage_range": {

                            "type": "array",
                            "minItems": 1,
                            "maxItems": 10,
                            "items": {

                                "type": "integer"
                            }
                        }
                    }
                ]
            }
        }
    }
}

Using jsonschema I validate the whole schema file OK. However, on writing unittests I get the following error;

capacity = {'oneOf': [{'max_percentage': {'type': 'integer', 'minimum': 1, 'maximum': 150}, 'min_percentage': {'type': 'integer', 'minimum': 1, 'maximum': {'$ref': '#/properties/traffic_parameters/capacity/oneOf/max_percentage/minimum'}}}, {'percentage_range': {'type': 'array', 'minItems': 1, 'maxItems': 10, 'items': {'type': 'integer'}}}]}
-----------------------------------------
index0 = {'max_percentage': {'type': 'integer', 'minimum': 1, 'maximum': 150}, 'min_percentage': {'type': 'integer', 'minimum': 1, 'maximum': {'$ref': '#/properties/traffic_parameters/capacity/oneOf/max_percentage/minimum'}}}
-----------------------------------------
min_percentage = {'type': 'integer', 'minimum': 1, 'maximum': {'$ref': '#/properties/traffic_parameters/capacity/oneOf/max_percentage/minimum'}}
E.........
======================================================================
ERROR: test_invalid_minimum__traffic_parameters__capacity__min_percentage (__main__.SchemaTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_test-variables_schema.py", line 160, in test_invalid_minimum__traffic_parameters__capacity__min_percentage
    validate(0, min_percentage)
  File "/local/tools/PACKAGES/python3/lib/python3.6/site-packages/jsonschema/validators.py", line 540, in validate
    cls.check_schema(schema)
  File "/local/tools/PACKAGES/python3/lib/python3.6/site-packages/jsonschema/validators.py", line 83, in check_schema
    raise SchemaError.create_from(error)
jsonschema.exceptions.SchemaError: {'$ref': '#/properties/traffic_parameters/capacity/oneOf/max_percentage/minimum'} is not of type 'number'

Failed validating 'type' in schema['properties']['maximum']:
    {'type': 'number'}

On instance['maximum']:
{'$ref': '#/properties/traffic_parameters/capacity/oneOf/max_percentage/minimum'}


    FAILED (errors=1)

My test are Python unit tests that tests the minimum and maximum of the attribute. The maximum being a ref to another attribute defined directly above.

The test shown tests the minimum but it is the maximum value that is in error. The error would be the same if I were testing the maximum, it's just what I was working on.

I tried re-specifying the type as "integer" for "maximum" but the error remains.

How can I get past this error without changing the type of the attribute? The reference is important because I want the maximum of this attribute to be directly related to the minimum of the previous attribute.

Also, is there another (easier) way to reference these variables in unittests?

Here's the function

def test_invalid_minimum__traffic_parameters__capacity__min_percentage(self):
    global test_schema

    capacity = test_schema["traffic_parameters"]["capacity"]
    print ("capacity = " + str(capacity))
    print ("-----------------------------------------")

    index0 = capacity["oneOf"][0]
    print ("index0 = " + str(index0))
    print ("-----------------------------------------")

    min_percentage = index0["min_percentage"]
    print ("min_percentage = " + str(min_percentage))

    with self.assertRaises(ValidationError ):
        validate(0, min_percentage)

Thanks.

Upvotes: 0

Views: 289

Answers (2)

erosb
erosb

Reputation: 3141

This won't work this way. $ref references must always point to schemas. So it can be an object or a boolean, but not a number.

Upvotes: 1

Jason Desrosiers
Jason Desrosiers

Reputation: 24489

The JSON Reference spec doesn't place any limits on what can be $ref'd, but in practice, any validator that I have ever seen only supports $refs that point to a JSON Schema. I'm not sure why none ever supported that functionality, but I have yet to see a case where I thought it was a good idea to do such a thing.

In the recently released JSON Schema draft-06, the common practice of supporting only JSON Schemas became a rule. So, even if you do find a validator that supports $refing integers, I wouldn't recommend using it because it will make it harder to upgrade in the future.

Upvotes: 1

Related Questions