monochange_deno 0.5.1

Deno workspace and package discovery for monochange
Documentation
use std::path::PathBuf;

use monochange_core::FileChangeKind;

use super::*;

#[test]
fn analyze_manifest_change_reports_export_import_and_task_diffs() {
	let change = AnalyzedFileChange {
		path: PathBuf::from("deno.json"),
		package_path: PathBuf::from("deno.json"),
		kind: FileChangeKind::Modified,
		before_contents: Some(
			serde_json::json!({
				"exports": "./mod.ts",
				"imports": {"@std/assert": "jsr:@std/assert@1.0.0"},
				"tasks": {"test": "deno test"}
			})
			.to_string(),
		),
		after_contents: Some(
			serde_json::json!({
				"exports": {".": "./mod.ts", "./cli": "./cli.ts"},
				"imports": {
					"@std/assert": "jsr:@std/assert@1.0.0",
					"npm:zod": "npm:zod@3.24.0"
				},
				"tasks": {"test": "deno test", "lint": "deno lint"},
				"compilerOptions": {"jsx": "react-jsx"}
			})
			.to_string(),
		),
	};
	let mut warnings = Vec::new();
	let changes = analyze_manifest_change(&change, &mut warnings);

	assert!(warnings.is_empty());
	assert!(changes.iter().any(|change| {
		change.category == SemanticChangeCategory::Export
			&& change.item_path == "./cli"
			&& change.kind == SemanticChangeKind::Added
	}));
	assert!(changes.iter().any(|change| {
		change.category == SemanticChangeCategory::Dependency
			&& change.item_path == "npm:zod"
			&& change.kind == SemanticChangeKind::Added
	}));
	assert!(changes.iter().any(|change| {
		change.category == SemanticChangeCategory::Metadata
			&& change.item_path == "task.lint"
			&& change.kind == SemanticChangeKind::Added
	}));
	assert!(changes.iter().any(|change| {
		change.category == SemanticChangeCategory::Metadata
			&& change.item_path == "compiler_options.jsx"
			&& change.kind == SemanticChangeKind::Added
	}));
}

#[test]
fn manifest_helpers_cover_parse_failures_removed_entries_and_metadata() {
	assert!(is_manifest_file(Path::new("deno.jsonc")));
	assert!(!is_manifest_file(Path::new("mod.ts")));

	let mut warnings = Vec::new();
	assert!(parse_manifest(Some("{"), Path::new("deno.json"), &mut warnings).is_none());
	assert_eq!(warnings.len(), 1);

	let before = serde_json::json!({
		"exports": {".": "./mod.ts", "./cli": "./cli.ts"},
		"imports": {"@std/assert": "jsr:@std/assert@1.0.0"},
		"tasks": {"lint": "deno lint"},
		"compilerOptions": {"jsx": "react-jsx"},
		"lock": true
	});
	let after = serde_json::json!({
		"exports": {".": "./mod.ts"},
		"imports": {},
		"tasks": {},
		"compilerOptions": {},
		"lock": false
	});
	let export_changes = compare_manifest_entries(
		SemanticChangeCategory::Export,
		Path::new("deno.json"),
		&extract_export_entries(&before),
		&extract_export_entries(&after),
	);
	assert!(export_changes.iter().any(|change| {
		change.item_path == "./cli" && change.kind == SemanticChangeKind::Removed
	}));

	let mut nested_exports = BTreeMap::new();
	collect_export_entries(
		"runtime",
		&serde_json::json!({".": "./mod.ts", "./cli": "./cli.ts", "types": "./mod.d.ts"}),
		&mut nested_exports,
	);
	assert!(nested_exports.contains_key("."));
	assert!(nested_exports.contains_key("./cli"));
	assert!(!nested_exports.contains_key("runtime"));

	let metadata_changes = compare_manifest_entries(
		SemanticChangeCategory::Metadata,
		Path::new("deno.json"),
		&extract_metadata_entries(&before),
		&extract_metadata_entries(&after),
	);
	assert!(metadata_changes.iter().any(|change| {
		change.item_path == "lock" && change.kind == SemanticChangeKind::Modified
	}));
	assert!(metadata_changes.iter().any(|change| {
		change.item_path == "task.lint" && change.kind == SemanticChangeKind::Removed
	}));

	let metadata_entries = extract_metadata_entries(&serde_json::json!({
		"tasks": {"lint": "deno lint"},
		"compilerOptions": {"jsxImportSource": "preact"},
		"vendor": true
	}));
	assert!(metadata_entries.contains_key("task.lint"));
	assert!(metadata_entries.contains_key("compiler_options.jsxImportSource"));
	assert!(metadata_entries.contains_key("vendor"));

	assert!(describe_json_value(&serde_json::json!({"b": 2, "a": [1, 2]})).contains("a=1, 2"));
	assert_eq!(describe_json_value(&serde_json::json!(null)), "null");
	assert_eq!(describe_json_value(&serde_json::json!(3)), "3");
	assert_eq!(describe_json_value(&serde_json::json!("deno")), "deno");
}