Skip to content

Commit

Permalink
Start thiserror
Browse files Browse the repository at this point in the history
  • Loading branch information
theory committed Nov 12, 2024
1 parent c721d1c commit 1ede759
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 29 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ serde = { version = "1", features = ["derive"] }
serde_json = "1.0"
serde_with = { version = "3.9.0", features = ["hex"] }
spdx = "0.10.6"
thiserror = "1.0"
wax = "0.6.0"

[build-dependencies]
Expand Down
12 changes: 12 additions & 0 deletions src/error/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//! PGXN Meta Errors.
#[cfg(test)]
mod tests;

/// Build errors.
#[derive(thiserror::Error, Debug)]
pub enum Error {
/// License Error.
#[error("{}", .0.reason)]
License(#[from] spdx::error::ParseError),
}
11 changes: 11 additions & 0 deletions src/error/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use super::*;

#[test]
fn spdx() {
let parse_error = spdx::Expression::parse("not a license").unwrap_err();
let exp = parse_error.reason.to_string();
let not_exp = parse_error.to_string();
let err = Error::License(parse_error);
assert_eq!(exp, err.to_string());
assert_ne!(not_exp, err.to_string());
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ files. It supports both the [v1] and [v2] specs.
*/

pub mod dist;
mod error;
pub mod release;
mod util; // private utilities
pub mod valid;
Expand Down
119 changes: 90 additions & 29 deletions src/valid/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,12 @@ pub fn spec_compiler() -> Compiler {

/// Returns an error if v is not a valid path.
fn is_path(v: &Value) -> Result<(), Box<dyn Error>> {
let Value::String(s) = v else {
Err("not a string")?
};
let Value::String(s) = v else { return Ok(()) };

let path = RelativePath::new(s);
for c in path.components() {
if c == Component::ParentDir {
Err("parent dir")?
Err("references parent dir")?
};
}

Expand All @@ -61,10 +59,8 @@ fn is_path(v: &Value) -> Result<(), Box<dyn Error>> {

/// Returns an error if vi is not a valid SPDX license expression.
fn is_license(v: &Value) -> Result<(), Box<dyn Error>> {
let Value::String(s) = v else {
Err("not a string")?
};
_ = spdx::Expression::parse(s)?;
let Value::String(s) = v else { return Ok(()) };
_ = spdx::Expression::parse(s).map_err(crate::error::Error::License)?;
Ok(())
}

Expand Down Expand Up @@ -96,17 +92,17 @@ mod tests {
}

// Test invalid paths.
for invalid in [
json!("../outside/path"),
json!("thing/../other"),
json!({}),
json!([]),
json!(true),
json!(null),
json!(42),
for (name, invalid, err) in [
("parent", json!("../outside/path"), "references parent dir"),
(
"sub parent",
json!("thing/../other"),
"references parent dir",
),
] {
if is_path(&invalid).is_ok() {
panic!("{} unexpectedly passed!", invalid)
match is_path(&invalid) {
Ok(_) => panic!("{name} unexpectedly passed!"),
Err(e) => assert_eq!(err, e.to_string(), "{name}"),
}
}
}
Expand Down Expand Up @@ -137,22 +133,87 @@ mod tests {
}

// Test invalid licenses.
for invalid_license in [
json!(""),
json!(null),
json!("0"),
json!(0),
json!("\n\t"),
json!("()"),
json!("AND"),
json!("OR"),
for (name, invalid_license, reason) in [
("empty string", json!(""), spdx::error::Reason::Empty),
("zero", json!("0"), spdx::error::Reason::UnknownTerm),
("control chars", json!("\n\t"), spdx::error::Reason::Empty),
(
"parens",
json!("()"),
spdx::error::Reason::Unexpected(&["<license>", "("]),
),
(
"and",
json!("AND"),
spdx::error::Reason::Unexpected(&["<license>", "("]),
),
(
"or",
json!("OR"),
spdx::error::Reason::Unexpected(&["<license>", "("]),
),
] {
if is_license(&invalid_license).is_ok() {
panic!("{} unexpectedly passed!", invalid_license)
match is_license(&invalid_license) {
Ok(_) => panic!("{name} unexpectedly passed!"),
Err(e) => assert_eq!(reason.to_string(), e.to_string(), "{name}"),
}
}
}

#[test]
fn test_spec_compiler() -> Result<(), Box<dyn Error>> {
let mut c = spec_compiler();
let id = "format";
// Compile simple schema to validate license and path.
c.add_resource(
id,
json!({
"type": "object",
"properties": {
"path": {
"type": "string",
"format": "path",
},
"license": {
"type": "string",
"format": "license",
}
}
}),
)?;

let mut schemas = Schemas::new();
let idx = c.compile(id, &mut schemas)?;

for (name, json, err) in [
(
"empty license",
json!({"license": ""}),
"at '/license': '' is not valid license: empty expression",
),
(
"zero license",
json!({"license": "0"}),
"at '/license': '0' is not valid license: unknown term",
),
(
"parent path",
json!({"path": "../foo"}),
"'../foo' is not valid path: references parent dir",
),
] {
match schemas.validate(&json, idx) {
Ok(_) => panic!("{name} unexpectedly succeeded"),
Err(e) => {
println!("{e}");
assert!(e.to_string().contains(err), "{name}")
}
}
}

Ok(())
}

#[test]
fn test_new() -> Result<(), Box<dyn Error>> {
let mut compiler = new();
Expand Down

0 comments on commit 1ede759

Please sign in to comment.