diff --git a/schema/v1/bugtracker.schema.json b/schema/v1/bugtracker.schema.json index d31623e..61f8e49 100644 --- a/schema/v1/bugtracker.schema.json +++ b/schema/v1/bugtracker.schema.json @@ -22,7 +22,7 @@ { "required": ["web", "mailto"] } ], "patternProperties": { - "^[xX]_": { + "^[xX]_.": { "description": "Custom key" } }, diff --git a/schema/v1/distribution.schema.json b/schema/v1/distribution.schema.json index 58679ce..ec2b9d2 100644 --- a/schema/v1/distribution.schema.json +++ b/schema/v1/distribution.schema.json @@ -51,7 +51,7 @@ "resources": { "$ref": "resources.schema.json" } }, "patternProperties": { - "^[xX]_": { + "^[xX]_.": { "description": "Custom key" } }, diff --git a/schema/v1/extension.schema.json b/schema/v1/extension.schema.json index 7967a4b..c00ecc9 100644 --- a/schema/v1/extension.schema.json +++ b/schema/v1/extension.schema.json @@ -27,7 +27,7 @@ }, "required": ["file", "version"], "patternProperties": { - "^[xX]_": { + "^[xX]_.": { "description": "Custom key" } }, diff --git a/schema/v1/meta-spec.schema.json b/schema/v1/meta-spec.schema.json index 2f76ee9..2b69de9 100644 --- a/schema/v1/meta-spec.schema.json +++ b/schema/v1/meta-spec.schema.json @@ -8,7 +8,7 @@ "version": { "type": "string", "pattern": "^1[.]0[.][[:digit:]]+$", - "description": "The version of the PGXN Meta Spec against which the document was generated." + "description": "The version of the PGXN Meta Spec against which the document was generated. Must be 1.0.x." }, "url": { "type": "string", @@ -18,7 +18,7 @@ }, "required": ["version"], "patternProperties": { - "^[xX]_": { + "^[xX]_.": { "description": "Custom key" } }, diff --git a/schema/v1/no_index.schema.json b/schema/v1/no_index.schema.json index 7fd4057..b741e57 100644 --- a/schema/v1/no_index.schema.json +++ b/schema/v1/no_index.schema.json @@ -32,7 +32,7 @@ { "required": ["file", "directory"] } ], "patternProperties": { - "^[xX]_": { + "^[xX]_.": { "description": "Custom key" } }, diff --git a/schema/v1/prereq_phase.schema.json b/schema/v1/prereq_phase.schema.json index 5f0904c..71119d6 100644 --- a/schema/v1/prereq_phase.schema.json +++ b/schema/v1/prereq_phase.schema.json @@ -23,7 +23,7 @@ } }, "patternProperties": { - "^[xX]_": { + "^[xX]_.": { "description": "Custom key" } }, diff --git a/schema/v1/prereqs.schema.json b/schema/v1/prereqs.schema.json index 1da32ad..6c706dc 100644 --- a/schema/v1/prereqs.schema.json +++ b/schema/v1/prereqs.schema.json @@ -29,7 +29,7 @@ "minProperties": 1, "$comment": "Really should require at least one of the named properties; this allows for a single _x property. Good enough for now.", "patternProperties": { - "^[xX]_": { + "^[xX]_.": { "description": "Custom key" } }, diff --git a/schema/v1/repository.schema.json b/schema/v1/repository.schema.json index a31b1e8..0e04b99 100644 --- a/schema/v1/repository.schema.json +++ b/schema/v1/repository.schema.json @@ -17,7 +17,6 @@ }, "type": { "type": "string", - "format": "email", "description": "a lowercase string indicating the VCS used." } }, @@ -27,7 +26,7 @@ { "required": ["web", "url", "type"] } ], "patternProperties": { - "^[xX]_": { + "^[xX]_.": { "description": "Custom key" } }, diff --git a/schema/v1/resources.schema.json b/schema/v1/resources.schema.json index 8ec9b33..6c07219 100644 --- a/schema/v1/resources.schema.json +++ b/schema/v1/resources.schema.json @@ -14,7 +14,7 @@ "repository": { "$ref": "repository.schema.json" } }, "patternProperties": { - "^[xX]_": { + "^[xX]_.": { "description": "Custom key" } }, diff --git a/spec.md b/spec.md index 7854e5e..c9c9574 100644 --- a/spec.md +++ b/spec.md @@ -349,7 +349,7 @@ are valid in the [List](#List) representation: mozilla_1_0 | Mozilla Public License, Version 1.0 mozilla_1_1 | Mozilla Public License, Version 1.1 openssl | OpenSSL License - perl_5 | The Perl 5 License (Artistic 1 & GPL 1 or later) + perl_5 | The Perl 5 License (Artistic 1 & GPL 1 or later) postgresql | The PostgreSQL License qpl_1_0 | Q Public License, Version 1.0 ssleay | Original SSLeay License diff --git a/tests/test.rs b/tests/test.rs index 4f0a466..2e215f6 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -12,6 +12,7 @@ const SCHEMA_ID: &str = "https://pgxn.org/meta/v1/distribution.schema.json"; #[test] fn test_schema_v1() -> Result<(), Box> { let mut compiler = Compiler::new(); + compiler.enable_format_assertions(); let mut loaded: HashMap> = HashMap::new(); let paths = fs::read_dir("./schema/v1")?; @@ -64,6 +65,7 @@ fn test_schema_v1() -> Result<(), Box> { fn new_compiler(dir: &str) -> Result> { let mut compiler = Compiler::new(); + compiler.enable_format_assertions(); let paths = fs::read_dir(dir)?; for path in paths { let path = path?.path(); @@ -501,7 +503,7 @@ fn test_v1_license() -> Result<(), Box> { json!(["nonesuch"]), json!([]), json!({}), - json!({"foo": ["not a uri"]}), + json!({"foo": ":hello"}), ] { if schemas.validate(&invalid_license, idx).is_ok() { panic!("{} unexpectedly passed!", invalid_license) @@ -597,6 +599,10 @@ fn test_v1_provides() -> Result<(), Box> { "null file", json!({"x": {"file": null, "version": "1.0.0"}}), ), + ( + "bare x_", + json!({"x": {"file": "x.txt", "version": "1.0.0", "x_": 0}}), + ), ] { if schemas.validate(&invalid_provides.1, idx).is_ok() { panic!("{} unexpectedly passed!", invalid_provides.0) @@ -674,6 +680,14 @@ fn test_v1_extension() -> Result<(), Box> { "invalid field", json!({"file": "widget.sql", "version": "0.26.0", "foo": "hi", }), ), + ( + "bare x_", + json!( { + "file": "widget.sql", + "version": "0.26.0", + "x_": "hi", + }), + ), // File ("no file", json!({"version": "0.26.0"})), ("null file", json!({"file": null, "version": "0.26.0"})), @@ -822,3 +836,110 @@ fn test_v1_maintainer() -> Result<(), Box> { Ok(()) } + +#[test] +fn test_v1_meta_spec() -> Result<(), Box> { + // Load the schemas and compile the maintainer schema. + let mut compiler = new_compiler("schema/v1")?; + let mut schemas = Schemas::new(); + let id = format!("{SCHEMA_BASE}/meta-spec.schema.json"); + let idx = compiler.compile(&id, &mut schemas)?; + + for valid_meta_spec in [ + ("version 1.0.0 only", json!({"version": "1.0.0"})), + ("version 1.0.1 only", json!({"version": "1.0.1"})), + ("version 1.0.2 only", json!({"version": "1.0.2"})), + ("version 1.0.99 only", json!({"version": "1.0.99"})), + ("x key", json!({"version": "1.0.99", "x_y": true})), + ("X key", json!({"version": "1.0.99", "X_x": true})), + ( + "version plus URL", + json!({"version": "1.0.0", "url": "https://pgxn.org/meta/spec.txt"}), + ), + ] { + if let Err(e) = schemas.validate(&valid_meta_spec.1, idx) { + panic!("extension {} failed: {e}", valid_meta_spec.0); + } + } + + for invalid_meta_spec in [ + ("array", json!([])), + ("string", json!("1.0.0")), + ("empty string", json!("")), + ("true", json!(true)), + ("false", json!(false)), + ("null", json!(null)), + ("empty object", json!({})), + ("unknown field", json!({"version": "1.0.0", "foo": "hi"})), + ("bare x_", json!({"version": "1.0.0", "x_": "hi"})), + ("version 1.1.0", json!({"version": "1.1.0"})), + ("version 2.0.0", json!({"version": "2.0.0"})), + ( + "no_version", + json!({"url": "https://pgxn.org/meta/spec.txt"}), + ), + ( + "invalid url", + json!({"version": "1.0.1", "url": "https://pgxn.org/meta/spec.html"}), + ), + ] { + if schemas.validate(&invalid_meta_spec.1, idx).is_ok() { + panic!("{} unexpectedly passed!", invalid_meta_spec.0) + } + } + + Ok(()) +} + +#[test] +fn test_v1_bugtracker() -> Result<(), Box> { + // Load the schemas and compile the maintainer schema. + let mut compiler = new_compiler("schema/v1")?; + let mut schemas = Schemas::new(); + let id = format!("{SCHEMA_BASE}/bugtracker.schema.json"); + let idx = compiler.compile(&id, &mut schemas)?; + + for valid_bugtracker in [ + ("web only", json!({"web": "https://foo.com"})), + ("mailto only", json!({"mailto": "hi@example.com"})), + ( + "web and mailto", + json!({"web": "https://foo.com", "mailto": "hi@example.com"}), + ), + ("x key", json!({"web": "https://foo.com", "x_q": true})), + ("X key", json!({"web": "https://foo.com", "X_hi": true})), + ] { + if let Err(e) = schemas.validate(&valid_bugtracker.1, idx) { + panic!("extension {} failed: {e}", valid_bugtracker.0); + } + } + + for invalid_bugtracker in [ + ("array", json!([])), + ("string", json!("web")), + ("empty string", json!("")), + ("true", json!(true)), + ("false", json!(false)), + ("null", json!(null)), + ("empty object", json!({})), + ("unknown field", json!({"web": "https://foo.com", "foo": 0})), + ("bare x_", json!({"web": "https://foo.com", "x_": 0})), + ("web array", json!({"web": []})), + ("web object", json!({"web": {}})), + ("web bool", json!({"web": true})), + ("web null", json!({"web": null})), + ("web number", json!({"web": 52})), + ("mailto array", json!({"mailto": []})), + ("mailto object", json!({"mailto": {}})), + ("mailto bool", json!({"mailto": true})), + ("mailto null", json!({"mailto": null})), + ("mailto number", json!({"mailto": 52})), + ("invalid web url", json!({"web": "3ttp://a.com"})), + ] { + if schemas.validate(&invalid_bugtracker.1, idx).is_ok() { + panic!("{} unexpectedly passed!", invalid_bugtracker.0) + } + } + + Ok(()) +}