Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions src/envelope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,60 @@ mod tests {
assert_eq!(typed["results"], serde_json::json!(["x", "y"]));
}

#[test]
fn resource_is_byte_identical_to_hand_rolled_json() {
// Same migration guarantee the action/versioned dialects assert: the
// resource dialect must serialize identically to the hand-rolled form
// it replaced, so adopting the helper is never a wire change.
let built = resource(
1,
"plugins",
vec![serde_json::json!({ "name": "github", "version": "0.4.0" })],
);
let hand = serde_json::json!({
"schema_version": 1,
"plugins": [{ "name": "github", "version": "0.4.0" }],
});
assert_eq!(
serde_json::to_string_pretty(&built).unwrap(),
serde_json::to_string_pretty(&hand).unwrap()
);
}

#[test]
fn versioned_flattens_a_serialized_struct_alongside_schema_version() {
// The shape `plugins validate` / `lanes validate` emit: a report struct
// is serialized to a Value, then wrapped. The report's own fields must
// stay at the top level next to `schema_version`, not nested under a
// key, and the result must match the hand-rolled equivalent.
#[derive(Serialize)]
struct Report {
path: String,
lane_count: usize,
errors: Vec<String>,
warnings: Vec<String>,
}
let report = Report {
path: "fledge.toml".to_string(),
lane_count: 3,
errors: vec![],
warnings: vec!["unpinned step".to_string()],
};

let built = versioned(1, serde_json::to_value(&report).unwrap());
let hand = serde_json::json!({
"schema_version": 1,
"path": "fledge.toml",
"lane_count": 3,
"errors": [],
"warnings": ["unpinned step"],
});
assert_eq!(
serde_json::to_string_pretty(&built).unwrap(),
serde_json::to_string_pretty(&hand).unwrap()
);
}

#[test]
fn action_leads_with_schema_version_and_action_then_merges_fields() {
let out = action(
Expand Down
1 change: 1 addition & 0 deletions src/lanes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub(super) const LANES_SEARCH_SCHEMA: u32 = 1;
pub(super) const LANES_IMPORT_SCHEMA: u32 = 1;
pub(super) const LANES_CREATE_SCHEMA: u32 = 1;
pub(super) const LANES_PUBLISH_SCHEMA: u32 = 1;
pub(super) const LANES_VALIDATE_SCHEMA: u32 = 1;

#[derive(Debug, Deserialize)]
pub(super) struct FledgeFileWithLanes {
Expand Down
6 changes: 5 additions & 1 deletion src/lanes/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,11 @@ pub(crate) fn print_lane_report(
) -> Result<()> {
if json {
// Wrap with schema_version envelope (matches lanes list/run/search shape).
let value = crate::envelope::versioned(1, serde_json::to_value(report)?);
// The version comes from the named per-command constant rather than a
// literal so a future shape change bumps it in the same place as every
// other `lanes` envelope.
let value =
crate::envelope::versioned(super::LANES_VALIDATE_SCHEMA, serde_json::to_value(report)?);
println!("{}", serde_json::to_string_pretty(&value)?);
} else if report.errors.is_empty() && report.warnings.is_empty() {
println!(
Expand Down
1 change: 1 addition & 0 deletions src/plugin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ const PLUGINS_SEARCH_SCHEMA: u32 = 1;
const PLUGINS_RECOMMEND_SCHEMA: u32 = 1;
const PLUGINS_CREATE_SCHEMA: u32 = 1;
const PLUGINS_PUBLISH_SCHEMA: u32 = 1;
const PLUGINS_VALIDATE_SCHEMA: u32 = 1;

// ─── Types ───────────────────────────────────────────────────────────────────

Expand Down
8 changes: 7 additions & 1 deletion src/plugin/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,13 @@ pub(crate) fn print_plugin_report(
// schema_version (matches plugins list/audit/search shape).
// The full report is flattened so existing fields (path,
// plugin_name, errors, warnings) sit at the same level.
let value = crate::envelope::versioned(1, serde_json::to_value(report)?);
// The version comes from the named per-command constant rather than a
// literal so a future shape change bumps it in the same place as every
// other `plugins` envelope.
let value = crate::envelope::versioned(
super::PLUGINS_VALIDATE_SCHEMA,
serde_json::to_value(report)?,
);
println!("{}", serde_json::to_string_pretty(&value)?);
} else if report.errors.is_empty() && report.warnings.is_empty() {
let name = if report.plugin_name.is_empty() {
Expand Down
Loading