chore: Enforce clippy checks on testing code as well

Update github actions to use clippy-check in order to have nice PR reports as well
Clippy rules are a bit more related for testing code
This commit is contained in:
Samuele Maci 2020-07-18 19:04:29 +01:00 committed by Dmitry Dygalo
parent bfd508a98b
commit 865f46fe06
8 changed files with 184 additions and 179 deletions

View File

@ -158,16 +158,18 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
components: clippy
- uses: actions-rs/cargo@v1
- uses: actions-rs/clippy-check@v1
with:
command: clippy
args: -- -D warnings
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-targets --all-features -- -D warnings
benchmark:
name: Benchmark

View File

@ -123,11 +123,11 @@ mod tests {
use serde_json::{json, Value};
use test_case::test_case;
#[test_case(json!({"exclusiveMaximum": 1u64 << 54}), json!(1u64 << 54))]
#[test_case(json!({"exclusiveMaximum": 1i64 << 54}), json!(1i64 << 54))]
#[test_case(json!({"exclusiveMaximum": 1u64 << 54}), json!(1u64 << 54 + 1))]
#[test_case(json!({"exclusiveMaximum": 1i64 << 54}), json!(1i64 << 54 + 1))]
fn is_not_valid(schema: Value, instance: Value) {
#[test_case(&json!({"exclusiveMaximum": 1u64 << 54}), &json!(1u64 << 54))]
#[test_case(&json!({"exclusiveMaximum": 1i64 << 54}), &json!(1i64 << 54))]
#[test_case(&json!({"exclusiveMaximum": 1u64 << 54}), &json!((1u64 << 54) + 1))]
#[test_case(&json!({"exclusiveMaximum": 1i64 << 54}), &json!((1i64 << 54) + 1))]
fn is_not_valid(schema: &Value, instance: &Value) {
tests_util::is_not_valid(schema, instance)
}
}

View File

@ -123,11 +123,11 @@ mod tests {
use serde_json::{json, Value};
use test_case::test_case;
#[test_case(json!({"exclusiveMinimum": 1u64 << 54}), json!(1u64 << 54))]
#[test_case(json!({"exclusiveMinimum": 1i64 << 54}), json!(1i64 << 54))]
#[test_case(json!({"exclusiveMinimum": 1u64 << 54}), json!(1u64 << 54 - 1))]
#[test_case(json!({"exclusiveMinimum": 1i64 << 54}), json!(1i64 << 54 - 1))]
fn is_not_valid(schema: Value, instance: Value) {
#[test_case(&json!({"exclusiveMinimum": 1u64 << 54}), &json!(1u64 << 54))]
#[test_case(&json!({"exclusiveMinimum": 1i64 << 54}), &json!(1i64 << 54))]
#[test_case(&json!({"exclusiveMinimum": 1u64 << 54}), &json!((1u64 << 54) - 1))]
#[test_case(&json!({"exclusiveMinimum": 1i64 << 54}), &json!((1i64 << 54) - 1))]
fn is_not_valid(schema: &Value, instance: &Value) {
tests_util::is_not_valid(schema, instance)
}
}

View File

@ -123,9 +123,9 @@ mod tests {
use serde_json::{json, Value};
use test_case::test_case;
#[test_case(json!({"maximum": 1u64 << 54}), json!(1u64 << 54 + 1))]
#[test_case(json!({"maximum": 1i64 << 54}), json!(1i64 << 54 + 1))]
fn is_not_valid(schema: Value, instance: Value) {
#[test_case(&json!({"maximum": 1u64 << 54}), &json!((1u64 << 54) + 1))]
#[test_case(&json!({"maximum": 1i64 << 54}), &json!((1i64 << 54) + 1))]
fn is_not_valid(schema: &Value, instance: &Value) {
tests_util::is_not_valid(schema, instance)
}
}

View File

@ -123,9 +123,9 @@ mod tests {
use serde_json::{json, Value};
use test_case::test_case;
#[test_case(json!({"minimum": 1u64 << 54}), json!(1u64 << 54 - 1))]
#[test_case(json!({"minimum": 1i64 << 54}), json!(1i64 << 54 - 1))]
fn is_not_valid(schema: Value, instance: Value) {
#[test_case(&json!({"minimum": 1u64 << 54}), &json!((1u64 << 54) - 1))]
#[test_case(&json!({"minimum": 1i64 << 54}), &json!((1i64 << 54) - 1))]
fn is_not_valid(schema: &Value, instance: &Value) {
tests_util::is_not_valid(schema, instance)
}
}

View File

@ -84,119 +84,119 @@ mod tests {
use serde_json::{json, Value};
use test_case::test_case;
#[test_case(json!({"additionalItems": false, "items": [{"type": "string"}]}), "additionalItems: false")]
#[test_case(json!({"additionalItems": {"type": "integer"}, "items": [{"type": "string"}]}), "additionalItems: {type: integer}")]
#[test_case(json!({"additionalProperties": {"type": "string"}}), "additionalProperties: {type: string}")]
#[test_case(json!({"additionalProperties": {"type": "string"}, "properties": {"foo": {}}}), "additionalProperties: {type: string}")]
#[test_case(json!({"additionalProperties": {"type": "string"}, "patternProperties": {"f.*o": {"type": "integer"}}}), "additionalProperties: {type: string}")]
#[test_case(json!({"additionalProperties": {"type": "string"}, "properties": {"foo": {}}, "patternProperties": {"f.*o": {"type": "integer"}}}), "additionalProperties: {type: string}")]
#[test_case(json!({"additionalProperties": false}), "additionalProperties: false")]
#[test_case(json!({"additionalProperties": false, "properties": {"foo": {}}}), "additionalProperties: false")]
#[test_case(json!({"additionalProperties": false, "patternProperties": {"f.*o": {"type": "integer"}}}), "additionalProperties: false")]
#[test_case(json!({"additionalProperties": false, "properties": {"foo": {}}, "patternProperties": {"f.*o": {"type": "integer"}}}), "additionalProperties: false")]
#[test_case(json!({"allOf": [{"type": "integer"}, {"minimum": 2}]}), "allOf: [{type: integer}, {minimum: 2}]")]
#[test_case(json!({"anyOf": [{"type": "integer"}, {"minimum": 2}]}), "anyOf: [{type: integer}, {minimum: 2}]")]
#[test_case(json!(true), "true")]
#[test_case(json!(false), "false")]
#[test_case(json!({"const": 1}), "const: 1")]
#[test_case(json!({"contains": {"minimum": 5}}), "contains: {minimum: 5}")]
#[test_case(json!({"contentMediaType": "application/json"}), "contentMediaType: application/json")]
#[test_case(json!({"contentEncoding": "base64"}), "contentEncoding: base64")]
#[test_case(json!({"contentEncoding": "base64", "contentMediaType": "application/json"}), "{contentMediaType: application/json, contentEncoding: base64}")]
#[test_case(json!({"dependencies": {"bar": ["foo"]}}), "dependencies: {bar: {required: [foo]}}")]
#[test_case(json!({"enum": [1]}), "enum: [1]")]
#[test_case(json!({"exclusiveMaximum": 1}), "exclusiveMaximum: 1")]
#[test_case(json!({"exclusiveMinimum": 1}), "exclusiveMinimum: 1")]
#[test_case(json!({"format": "date"}), "format: date")]
#[test_case(json!({"format": "date-time"}), "format: date-time")]
#[test_case(json!({"format": "email"}), "format: email")]
#[test_case(json!({"format": "hostname"}), "format: hostname")]
#[test_case(json!({"format": "idn-email"}), "format: idn-email")]
#[test_case(json!({"format": "idn-hostname"}), "format: idn-hostname")]
#[test_case(json!({"format": "ipv4"}), "format: ipv4")]
#[test_case(json!({"format": "ipv6"}), "format: ipv6")]
#[test_case(json!({"format": "iri"}), "format: iri")]
#[test_case(json!({"format": "iri-reference"}), "format: iri-reference")]
#[test_case(json!({"format": "json-pointer"}), "format: json-pointer")]
#[test_case(json!({"format": "regex"}), "format: regex")]
#[test_case(json!({"format": "relative-json-pointer"}), "format: relative-json-pointer")]
#[test_case(json!({"format": "time"}), "format: time")]
#[test_case(json!({"format": "uri"}), "format: uri")]
#[test_case(json!({"format": "uri-reference"}), "format: uri-reference")]
#[test_case(json!({"format": "uri-template"}), "format: uri-template")]
#[test_case(json!({"if": {"exclusiveMaximum": 0}, "then": {"minimum": -10}}), "if: {exclusiveMaximum: 0}, then: {minimum: -10}")]
#[test_case(json!({"if": {"exclusiveMaximum": 0}, "else": {"minimum": -10}}), "if: {exclusiveMaximum: 0}, else: {minimum: -10}")]
#[test_case(json!({"if": {"exclusiveMaximum": 0}, "then": {"minimum": -10}, "else": {"multipleOf": 2}}), "if: {exclusiveMaximum: 0}, then: {minimum: -10}, else: {multipleOf: 2}")]
#[test_case(json!({"items": [{"type": "string"}]}), "items: [{type: string}]")]
#[test_case(json!({"items": {"type": "integer"}}), "items: {type: integer}")]
#[test_case(json!({"items": {"type": "integer", "minimum": 4}}), "items: {minimum: 4, type: integer}")]
#[test_case(json!({"maxItems": 1}), "maxItems: 1")]
#[test_case(json!({"maxLength": 1}), "maxLength: 1")]
#[test_case(json!({"maxProperties": 1}), "maxProperties: 1")]
#[test_case(json!({"maximum": 1}), "maximum: 1")]
#[test_case(json!({"minItems": 1}), "minItems: 1")]
#[test_case(json!({"minLength": 1}), "minLength: 1")]
#[test_case(json!({"minProperties": 1}), "minProperties: 1")]
#[test_case(json!({"minimum": 1}), "minimum: 1")]
#[test_case(json!({"multipleOf": 1}), "multipleOf: 1")]
#[test_case(json!({"multipleOf": 1.5}), "multipleOf: 1.5")]
#[test_case(json!({"not": true}), "not: true")]
#[test_case(json!({"oneOf": [{"type": "integer"}, {"minimum": 2}]}), "oneOf: [{type: integer}, {minimum: 2}]")]
#[test_case(json!({"pattern": "^a*$"}), "pattern: ^a*$")]
#[test_case(json!({"patternProperties": {"f.*o": {"type": "integer"}}}), "patternProperties: {f.*o: {type: integer}}")]
#[test_case(json!({"properties": {"foo": {}}}), "properties: {foo: {}}")]
#[test_case(json!({"propertyNames": {"maxLength": 3}}), "propertyNames: {maxLength: 3}")]
#[test_case(json!({"propertyNames": false}), "propertyNames: false")]
#[test_case(json!({"$ref": "#/properties/foo"}), "$ref: json-schema:///#/properties/foo")]
#[test_case(json!({"required": ["foo"]}), "required: [foo]")]
#[test_case(json!({"type": "null"}), "type: null")]
#[test_case(json!({"type": "boolean"}), "type: boolean")]
#[test_case(json!({"type": "string"}), "type: string")]
#[test_case(json!({"type": "array"}), "type: array")]
#[test_case(json!({"type": "object"}), "type: object")]
#[test_case(json!({"type": "number"}), "type: number")]
#[test_case(json!({"type": "integer"}), "type: integer")]
#[test_case(json!({"type": "integer", "$schema": "http://json-schema.org/draft-04/schema#"}), "type: integer")]
#[test_case(json!({"type": ["integer", "null"]}), "type: [integer, null]")]
#[test_case(json!({"type": ["integer", "null"], "$schema": "http://json-schema.org/draft-04/schema#"}), "type: [integer, null]")]
#[test_case(json!({"uniqueItems": true}), "uniqueItems: true")]
fn debug_representation(schema: Value, expected: &str) {
let compiled = JSONSchema::compile(&schema).unwrap();
#[test_case(&json!({"additionalItems": false, "items": [{"type": "string"}]}), "additionalItems: false")]
#[test_case(&json!({"additionalItems": {"type": "integer"}, "items": [{"type": "string"}]}), "additionalItems: {type: integer}")]
#[test_case(&json!({"additionalProperties": {"type": "string"}}), "additionalProperties: {type: string}")]
#[test_case(&json!({"additionalProperties": {"type": "string"}, "properties": {"foo": {}}}), "additionalProperties: {type: string}")]
#[test_case(&json!({"additionalProperties": {"type": "string"}, "patternProperties": {"f.*o": {"type": "integer"}}}), "additionalProperties: {type: string}")]
#[test_case(&json!({"additionalProperties": {"type": "string"}, "properties": {"foo": {}}, "patternProperties": {"f.*o": {"type": "integer"}}}), "additionalProperties: {type: string}")]
#[test_case(&json!({"additionalProperties": false}), "additionalProperties: false")]
#[test_case(&json!({"additionalProperties": false, "properties": {"foo": {}}}), "additionalProperties: false")]
#[test_case(&json!({"additionalProperties": false, "patternProperties": {"f.*o": {"type": "integer"}}}), "additionalProperties: false")]
#[test_case(&json!({"additionalProperties": false, "properties": {"foo": {}}, "patternProperties": {"f.*o": {"type": "integer"}}}), "additionalProperties: false")]
#[test_case(&json!({"allOf": [{"type": "integer"}, {"minimum": 2}]}), "allOf: [{type: integer}, {minimum: 2}]")]
#[test_case(&json!({"anyOf": [{"type": "integer"}, {"minimum": 2}]}), "anyOf: [{type: integer}, {minimum: 2}]")]
#[test_case(&json!(true), "true")]
#[test_case(&json!(false), "false")]
#[test_case(&json!({"const": 1}), "const: 1")]
#[test_case(&json!({"contains": {"minimum": 5}}), "contains: {minimum: 5}")]
#[test_case(&json!({"contentMediaType": "application/json"}), "contentMediaType: application/json")]
#[test_case(&json!({"contentEncoding": "base64"}), "contentEncoding: base64")]
#[test_case(&json!({"contentEncoding": "base64", "contentMediaType": "application/json"}), "{contentMediaType: application/json, contentEncoding: base64}")]
#[test_case(&json!({"dependencies": {"bar": ["foo"]}}), "dependencies: {bar: {required: [foo]}}")]
#[test_case(&json!({"enum": [1]}), "enum: [1]")]
#[test_case(&json!({"exclusiveMaximum": 1}), "exclusiveMaximum: 1")]
#[test_case(&json!({"exclusiveMinimum": 1}), "exclusiveMinimum: 1")]
#[test_case(&json!({"format": "date"}), "format: date")]
#[test_case(&json!({"format": "date-time"}), "format: date-time")]
#[test_case(&json!({"format": "email"}), "format: email")]
#[test_case(&json!({"format": "hostname"}), "format: hostname")]
#[test_case(&json!({"format": "idn-email"}), "format: idn-email")]
#[test_case(&json!({"format": "idn-hostname"}), "format: idn-hostname")]
#[test_case(&json!({"format": "ipv4"}), "format: ipv4")]
#[test_case(&json!({"format": "ipv6"}), "format: ipv6")]
#[test_case(&json!({"format": "iri"}), "format: iri")]
#[test_case(&json!({"format": "iri-reference"}), "format: iri-reference")]
#[test_case(&json!({"format": "json-pointer"}), "format: json-pointer")]
#[test_case(&json!({"format": "regex"}), "format: regex")]
#[test_case(&json!({"format": "relative-json-pointer"}), "format: relative-json-pointer")]
#[test_case(&json!({"format": "time"}), "format: time")]
#[test_case(&json!({"format": "uri"}), "format: uri")]
#[test_case(&json!({"format": "uri-reference"}), "format: uri-reference")]
#[test_case(&json!({"format": "uri-template"}), "format: uri-template")]
#[test_case(&json!({"if": {"exclusiveMaximum": 0}, "then": {"minimum": -10}}), "if: {exclusiveMaximum: 0}, then: {minimum: -10}")]
#[test_case(&json!({"if": {"exclusiveMaximum": 0}, "else": {"minimum": -10}}), "if: {exclusiveMaximum: 0}, else: {minimum: -10}")]
#[test_case(&json!({"if": {"exclusiveMaximum": 0}, "then": {"minimum": -10}, "else": {"multipleOf": 2}}), "if: {exclusiveMaximum: 0}, then: {minimum: -10}, else: {multipleOf: 2}")]
#[test_case(&json!({"items": [{"type": "string"}]}), "items: [{type: string}]")]
#[test_case(&json!({"items": {"type": "integer"}}), "items: {type: integer}")]
#[test_case(&json!({"items": {"type": "integer", "minimum": 4}}), "items: {minimum: 4, type: integer}")]
#[test_case(&json!({"maxItems": 1}), "maxItems: 1")]
#[test_case(&json!({"maxLength": 1}), "maxLength: 1")]
#[test_case(&json!({"maxProperties": 1}), "maxProperties: 1")]
#[test_case(&json!({"maximum": 1}), "maximum: 1")]
#[test_case(&json!({"minItems": 1}), "minItems: 1")]
#[test_case(&json!({"minLength": 1}), "minLength: 1")]
#[test_case(&json!({"minProperties": 1}), "minProperties: 1")]
#[test_case(&json!({"minimum": 1}), "minimum: 1")]
#[test_case(&json!({"multipleOf": 1}), "multipleOf: 1")]
#[test_case(&json!({"multipleOf": 1.5}), "multipleOf: 1.5")]
#[test_case(&json!({"not": true}), "not: true")]
#[test_case(&json!({"oneOf": [{"type": "integer"}, {"minimum": 2}]}), "oneOf: [{type: integer}, {minimum: 2}]")]
#[test_case(&json!({"pattern": "^a*$"}), "pattern: ^a*$")]
#[test_case(&json!({"patternProperties": {"f.*o": {"type": "integer"}}}), "patternProperties: {f.*o: {type: integer}}")]
#[test_case(&json!({"properties": {"foo": {}}}), "properties: {foo: {}}")]
#[test_case(&json!({"propertyNames": {"maxLength": 3}}), "propertyNames: {maxLength: 3}")]
#[test_case(&json!({"propertyNames": false}), "propertyNames: false")]
#[test_case(&json!({"$ref": "#/properties/foo"}), "$ref: json-schema:///#/properties/foo")]
#[test_case(&json!({"required": ["foo"]}), "required: [foo]")]
#[test_case(&json!({"type": "null"}), "type: null")]
#[test_case(&json!({"type": "boolean"}), "type: boolean")]
#[test_case(&json!({"type": "string"}), "type: string")]
#[test_case(&json!({"type": "array"}), "type: array")]
#[test_case(&json!({"type": "object"}), "type: object")]
#[test_case(&json!({"type": "number"}), "type: number")]
#[test_case(&json!({"type": "integer"}), "type: integer")]
#[test_case(&json!({"type": "integer", "$schema": "http://json-schema.org/draft-04/schema#"}), "type: integer")]
#[test_case(&json!({"type": ["integer", "null"]}), "type: [integer, null]")]
#[test_case(&json!({"type": ["integer", "null"], "$schema": "http://json-schema.org/draft-04/schema#"}), "type: [integer, null]")]
#[test_case(&json!({"uniqueItems": true}), "uniqueItems: true")]
fn debug_representation(schema: &Value, expected: &str) {
let compiled = JSONSchema::compile(schema).unwrap();
assert_eq!(format!("{:?}", compiled.validators[0]), expected);
}
#[test_case(json!({"items": [{}], "additionalItems": {"type": "integer"}}), json!([ null, 2, 3, "foo" ]), r#"'"foo"' is not of type 'integer'"#)]
#[test_case(json!({"items": [{}, {}, {}], "additionalItems": false}), json!([ 1, 2, 3, 4 ]), r#"Additional items are not allowed (4 was unexpected)"#)]
#[test_case(json!({"items": [{}, {}, {}], "additionalItems": false}), json!([ 1, 2, 3, 4, 5 ]), r#"Additional items are not allowed (4, 5 were unexpected)"#)]
#[test_case(json!({"properties": {"foo": {}, "bar": {}}, "patternProperties": { "^v": {} }, "additionalProperties": false}), json!({"foo" : 1, "bar" : 2, "quux" : "boom"}), r#"False schema does not allow '"quux"'"#)]
#[test_case(json!({"anyOf": [{"type": "integer"}, {"minimum": 2}]}), json!(1.5), r#"'1.5' is not valid under any of the given schemas"#)]
#[test_case(json!({"const": 2}), json!(5), r#"'2' was expected"#)]
#[test_case(json!({"contains": {"minimum": 5}}), json!([2, 3, 4]), r#"None of '[2,3,4]' are valid under the given schema"#)]
#[test_case(json!({"enum": [1, 2, 3]}), json!(4), r#"'4' is not one of '[1,2,3]'"#)]
#[test_case(json!({"exclusiveMaximum": 3.0}), json!(3.0), r#"3.0 is greater than or equal to the maximum of 3"#)]
#[test_case(json!({"exclusiveMinimum": 1.1}), json!(1.1), r#"1.1 is less than or equal to the minimum of 1.1"#)]
#[test_case(json!({"format": "ipv4"}), json!("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), r#"'"2001:0db8:85a3:0000:0000:8a2e:0370:7334"' is not a 'ipv4'"#)]
#[test_case(json!({"maximum": 3.0}), json!(3.5), r#"3.5 is greater than the maximum of 3"#)]
#[test_case(json!({"maxItems": 2}), json!([1, 2, 3]), r#"[1,2,3] has more than 2 items"#)]
#[test_case(json!({"maxLength": 2}), json!("foo"), r#"'"foo"' is longer than 2 characters"#)]
#[test_case(json!({"maxProperties": 2}), json!({"foo": 1, "bar": 2, "baz": 3}), r#"{"bar":2,"baz":3,"foo":1} has more than 2 properties"#)]
#[test_case(json!({"minimum": 1.1}), json!(0.6), r#"0.6 is less than the minimum of 1.1"#)]
#[test_case(json!({"minItems": 1}), json!([]), r#"[] has less than 1 item"#)]
#[test_case(json!({"minLength": 2}), json!("f"), r#"'"f"' is shorter than 2 characters"#)]
#[test_case(json!({"minProperties": 1}), json!({}), r#"{} has less than 1 property"#)]
#[test_case(json!({"multipleOf": 2}), json!(7), r#"7 is not a multiple of 2"#)]
#[test_case(json!({"not": {"type": "integer"}}), json!(1), r#"{"type":"integer"} is not allowed for 1"#)]
#[test_case(json!({"oneOf": [{"type": "integer"}, {"minimum": 2}]}), json!(1.1), r#"'1.1' is not valid under any of the given schemas"#)]
#[test_case(json!({"oneOf": [{"type": "integer"}, {"minimum": 2}]}), json!(3), r#"'3' is valid under more than one of the given schemas"#)]
#[test_case(json!({"pattern": "^a*$"}), json!("abc"), r#"'"abc"' does not match '^a*$'"#)]
#[test_case(json!({"properties": {"foo": {}, "bar": {}}, "required": ["foo"]}), json!({"bar": 1}), r#"'foo' is a required property"#)]
#[test_case(json!({"type": "integer"}), json!(1.1), r#"'1.1' is not of type 'integer'"#)]
#[test_case(json!({"type": ["integer", "string"]}), json!(null), r#"'null' is not of types 'integer', 'string'"#)]
#[test_case(json!({"uniqueItems": true}), json!([1, 1]), r#"'[1,1]' has non-unique elements"#)]
fn error_message(schema: Value, instance: Value, expected: &str) {
let compiled = JSONSchema::compile(&schema).unwrap();
#[test_case(&json!({"items": [{}], "additionalItems": {"type": "integer"}}), &json!([ null, 2, 3, "foo" ]), r#"'"foo"' is not of type 'integer'"#)]
#[test_case(&json!({"items": [{}, {}, {}], "additionalItems": false}), &json!([ 1, 2, 3, 4 ]), r#"Additional items are not allowed (4 was unexpected)"#)]
#[test_case(&json!({"items": [{}, {}, {}], "additionalItems": false}), &json!([ 1, 2, 3, 4, 5 ]), r#"Additional items are not allowed (4, 5 were unexpected)"#)]
#[test_case(&json!({"properties": {"foo": {}, "bar": {}}, "patternProperties": { "^v": {} }, "additionalProperties": false}), &json!({"foo" : 1, "bar" : 2, "quux" : "boom"}), r#"False schema does not allow '"quux"'"#)]
#[test_case(&json!({"anyOf": [{"type": "integer"}, {"minimum": 2}]}), &json!(1.5), r#"'1.5' is not valid under any of the given schemas"#)]
#[test_case(&json!({"const": 2}), &json!(5), r#"'2' was expected"#)]
#[test_case(&json!({"contains": {"minimum": 5}}), &json!([2, 3, 4]), r#"None of '[2,3,4]' are valid under the given schema"#)]
#[test_case(&json!({"enum": [1, 2, 3]}), &json!(4), r#"'4' is not one of '[1,2,3]'"#)]
#[test_case(&json!({"exclusiveMaximum": 3.0}), &json!(3.0), r#"3.0 is greater than or equal to the maximum of 3"#)]
#[test_case(&json!({"exclusiveMinimum": 1.1}), &json!(1.1), r#"1.1 is less than or equal to the minimum of 1.1"#)]
#[test_case(&json!({"format": "ipv4"}), &json!("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), r#"'"2001:0db8:85a3:0000:0000:8a2e:0370:7334"' is not a 'ipv4'"#)]
#[test_case(&json!({"maximum": 3.0}), &json!(3.5), r#"3.5 is greater than the maximum of 3"#)]
#[test_case(&json!({"maxItems": 2}), &json!([1, 2, 3]), r#"[1,2,3] has more than 2 items"#)]
#[test_case(&json!({"maxLength": 2}), &json!("foo"), r#"'"foo"' is longer than 2 characters"#)]
#[test_case(&json!({"maxProperties": 2}), &json!({"foo": 1, "bar": 2, "baz": 3}), r#"{"bar":2,"baz":3,"foo":1} has more than 2 properties"#)]
#[test_case(&json!({"minimum": 1.1}), &json!(0.6), r#"0.6 is less than the minimum of 1.1"#)]
#[test_case(&json!({"minItems": 1}), &json!([]), r#"[] has less than 1 item"#)]
#[test_case(&json!({"minLength": 2}), &json!("f"), r#"'"f"' is shorter than 2 characters"#)]
#[test_case(&json!({"minProperties": 1}), &json!({}), r#"{} has less than 1 property"#)]
#[test_case(&json!({"multipleOf": 2}), &json!(7), r#"7 is not a multiple of 2"#)]
#[test_case(&json!({"not": {"type": "integer"}}), &json!(1), r#"{"type":"integer"} is not allowed for 1"#)]
#[test_case(&json!({"oneOf": [{"type": "integer"}, {"minimum": 2}]}), &json!(1.1), r#"'1.1' is not valid under any of the given schemas"#)]
#[test_case(&json!({"oneOf": [{"type": "integer"}, {"minimum": 2}]}), &json!(3), r#"'3' is valid under more than one of the given schemas"#)]
#[test_case(&json!({"pattern": "^a*$"}), &json!("abc"), r#"'"abc"' does not match '^a*$'"#)]
#[test_case(&json!({"properties": {"foo": {}, "bar": {}}, "required": ["foo"]}), &json!({"bar": 1}), r#"'foo' is a required property"#)]
#[test_case(&json!({"type": "integer"}), &json!(1.1), r#"'1.1' is not of type 'integer'"#)]
#[test_case(&json!({"type": ["integer", "string"]}), &json!(null), r#"'null' is not of types 'integer', 'string'"#)]
#[test_case(&json!({"uniqueItems": true}), &json!([1, 1]), r#"'[1,1]' has non-unique elements"#)]
fn error_message(schema: &Value, instance: &Value, expected: &str) {
let compiled = JSONSchema::compile(schema).unwrap();
let errors: Vec<_> = compiled
.validate(&instance)
.validate(instance)
.expect_err(&format!(
"Validation error is expected. Schema=`{:?}` Instance=`{:?}`",
schema, instance
@ -206,45 +206,43 @@ mod tests {
}
// Extra cases not covered by JSON test suite
#[test_case(json!({"additionalProperties": {"type": "string"}}))]
#[test_case(json!({"additionalProperties": {"type": "string"}, "properties": {"foo": {}}}))]
#[test_case(json!({"additionalProperties": {"type": "string"}, "patternProperties": {"f.*o": {"type": "integer"}}}))]
#[test_case(json!({"additionalProperties": {"type": "string"}, "properties": {"foo": {}}, "patternProperties": {"f.*o": {"type": "integer"}}}))]
#[test_case(json!({"additionalProperties": false}))]
#[test_case(json!({"additionalProperties": false, "properties": {"foo": {}}}))]
#[test_case(json!({"additionalProperties": false, "patternProperties": {"f.*o": {"type": "integer"}}}))]
#[test_case(json!({"additionalProperties": false, "properties": {"foo": {}}, "patternProperties": {"f.*o": {"type": "integer"}}}))]
#[test_case(json!({"additionalItems": false, "items": [{"type": "string"}]}))]
#[test_case(json!({"additionalItems": {"type": "integer"}, "items": [{"type": "string"}]}))]
#[test_case(json!({"contains": {"minimum": 5}}))]
#[test_case(json!({"contentMediaType": "application/json"}))]
#[test_case(json!({"contentEncoding": "base64"}))]
#[test_case(json!({"contentEncoding": "base64", "contentMediaType": "application/json"}))]
#[test_case(json!({"dependencies": {"bar": ["foo"]}}))]
#[test_case(json!({"exclusiveMaximum": 5}))]
#[test_case(json!({"exclusiveMinimum": 5}))]
#[test_case(json!({"format": "ipv4"}))]
#[test_case(json!({"maximum": 2}))]
#[test_case(json!({"maxItems": 2}))]
#[test_case(json!({"maxProperties": 2}))]
#[test_case(json!({"minProperties": 2}))]
#[test_case(json!({"multipleOf": 2.5}))]
#[test_case(json!({"multipleOf": 2}))]
#[test_case(json!({"required": ["a"]}))]
#[test_case(json!({"pattern": "^a"}))]
#[test_case(json!({"patternProperties": {"f.*o": {"type": "integer"}}}))]
#[test_case(json!({"propertyNames": {"maxLength": 3}}))]
fn is_valid_another_type(schema: Value) {
#[test_case(&json!({"additionalProperties": {"type": "string"}}))]
#[test_case(&json!({"additionalProperties": {"type": "string"}, "properties": {"foo": {}}}))]
#[test_case(&json!({"additionalProperties": {"type": "string"}, "patternProperties": {"f.*o": {"type": "integer"}}}))]
#[test_case(&json!({"additionalProperties": {"type": "string"}, "properties": {"foo": {}}, "patternProperties": {"f.*o": {"type": "integer"}}}))]
#[test_case(&json!({"additionalProperties": false}))]
#[test_case(&json!({"additionalProperties": false, "properties": {"foo": {}}}))]
#[test_case(&json!({"additionalProperties": false, "patternProperties": {"f.*o": {"type": "integer"}}}))]
#[test_case(&json!({"additionalProperties": false, "properties": {"foo": {}}, "patternProperties": {"f.*o": {"type": "integer"}}}))]
#[test_case(&json!({"additionalItems": false, "items": [{"type": "string"}]}))]
#[test_case(&json!({"additionalItems": {"type": "integer"}, "items": [{"type": "string"}]}))]
#[test_case(&json!({"contains": {"minimum": 5}}))]
#[test_case(&json!({"contentMediaType": "application/json"}))]
#[test_case(&json!({"contentEncoding": "base64"}))]
#[test_case(&json!({"contentEncoding": "base64", "contentMediaType": "application/json"}))]
#[test_case(&json!({"dependencies": {"bar": ["foo"]}}))]
#[test_case(&json!({"exclusiveMaximum": 5}))]
#[test_case(&json!({"exclusiveMinimum": 5}))]
#[test_case(&json!({"format": "ipv4"}))]
#[test_case(&json!({"maximum": 2}))]
#[test_case(&json!({"maxItems": 2}))]
#[test_case(&json!({"maxProperties": 2}))]
#[test_case(&json!({"minProperties": 2}))]
#[test_case(&json!({"multipleOf": 2.5}))]
#[test_case(&json!({"multipleOf": 2}))]
#[test_case(&json!({"required": ["a"]}))]
#[test_case(&json!({"pattern": "^a"}))]
#[test_case(&json!({"patternProperties": {"f.*o": {"type": "integer"}}}))]
#[test_case(&json!({"propertyNames": {"maxLength": 3}}))]
fn is_valid_another_type(schema: &Value) {
let instance = json!(null);
let compiled = JSONSchema::compile(&schema).unwrap();
let compiled = JSONSchema::compile(schema).unwrap();
assert!(compiled.is_valid(&instance))
}
#[test_case(json!({"additionalProperties": false}), json!({}))]
#[test_case(json!({"additionalItems": false, "items": true}), json!([]))]
fn is_valid(schema: Value, instance: Value) {
let data = json!(instance);
let compiled = JSONSchema::compile(&schema).unwrap();
assert!(compiled.is_valid(&data))
#[test_case(&json!({"additionalProperties": false}), &json!({}))]
#[test_case(&json!({"additionalItems": false, "items": true}), &json!([]))]
fn is_valid(schema: &Value, instance: &Value) {
let compiled = JSONSchema::compile(schema).unwrap();
assert!(compiled.is_valid(instance))
}
}

View File

@ -56,7 +56,6 @@
clippy::cast_possible_truncation,
clippy::doc_markdown,
clippy::explicit_iter_loop,
clippy::integer_arithmetic,
clippy::map_unwrap_or,
clippy::match_same_arms,
clippy::needless_borrow,
@ -64,7 +63,6 @@
clippy::print_stdout,
clippy::redundant_closure,
clippy::trivially_copy_pass_by_ref,
clippy::unwrap_used,
missing_debug_implementations,
missing_docs,
trivial_casts,
@ -75,6 +73,8 @@
unreachable_pub,
variant_size_differences
)]
#![cfg(not(test))]
#![allow(clippy::integer_arithmetic, clippy::unwrap_used)]
mod compilation;
mod error;
mod keywords;
@ -106,16 +106,21 @@ pub fn is_valid(schema: &Value, instance: &Value) -> bool {
}
#[cfg(test)]
mod tests_util {
pub(crate) mod tests_util {
use super::JSONSchema;
use serde_json::Value;
pub(crate) fn is_not_valid(schema: Value, instance: Value) {
let compiled = JSONSchema::compile(&schema).unwrap();
assert!(!compiled.is_valid(&instance), "{} should not be valid");
pub(crate) fn is_not_valid(schema: &Value, instance: &Value) {
let compiled = JSONSchema::compile(schema).unwrap();
assert!(
compiled.validate(&instance).is_err(),
"{} should not be valid"
!compiled.is_valid(instance),
"{} should not be valid",
instance
);
assert!(
compiled.validate(instance).is_err(),
"{} should not be valid",
instance
);
}
}

View File

@ -135,12 +135,12 @@ mod tests {
use serde_json::{json, Value};
use test_case::test_case;
#[test_case(json!({"$schema": "http://json-schema.org/draft-07/schema#"}), Some(Draft::Draft7))]
#[test_case(json!({"$schema": "http://json-schema.org/draft-06/schema#"}), Some(Draft::Draft6))]
#[test_case(json!({"$schema": "http://json-schema.org/draft-04/schema#"}), Some(Draft::Draft4))]
#[test_case(json!({"$schema": "http://example.com/custom/schema#"}), None)]
fn test_draft_from_schema(schema: Value, draft: Option<Draft>) {
assert_eq!(draft_from_schema(&schema), draft)
#[test_case(&json!({"$schema": "http://json-schema.org/draft-07/schema#"}), Some(Draft::Draft7))]
#[test_case(&json!({"$schema": "http://json-schema.org/draft-06/schema#"}), Some(Draft::Draft6))]
#[test_case(&json!({"$schema": "http://json-schema.org/draft-04/schema#"}), Some(Draft::Draft4))]
#[test_case(&json!({"$schema": "http://example.com/custom/schema#"}), None)]
fn test_draft_from_schema(schema: &Value, draft: Option<Draft>) {
assert_eq!(draft_from_schema(schema), draft)
}
#[test]