use super::{Directory, fixture}; use dever::compiler::{build, project::Project}; #[test] fn map_order_value_copies_and_constructor_faults() { check( "storage.dever", &[ ("verify", None), ( "duplicateEntry", Some(("duplicate Map literal key", "{ first_key = 1")), ), ( "failureEntry", Some(("Problem.Denied", "Problem.Denied(\"first\")")), ), ( "faultEntry", Some(("integer arithmetic fault", "value + 1")), ), ( "lookupFailure", Some(("Problem.Denied", "Problem.Denied(\"first\")")), ), ( "lookupFault", Some(("integer arithmetic fault", "value + 1")), ), ( "staticLookupFailure", Some(("Problem.Denied", "Problem.Denied(\"first\")")), ), ( "staticMissingFailure", Some(("Problem.Denied", "Problem.Denied(\"first\")")), ), ], ); } #[test] fn literal_collections_evaluate_values_in_source_order() { let directory = Directory::new(); let project = Project::load(&fixture().with_file_name("storage.dever")).unwrap(); let program = project.check().unwrap(); let binary = build::build( &program, &project.sources, "traceLiteralLookup", &directory.0.join("trace"), ) .unwrap(); let output = std::process::Command::new(binary).output().unwrap(); assert!(output.status.success(), "{:?}", output.stderr); assert_eq!( output.stdout, b"first\nsecond\nthird\nfourth\nfifth\ntrue\n" ); } #[test] fn owned_accumulators_preserve_aliases_stop_order_and_failures() { check( "owned_state.dever", &[ ("verify", None), ( "failureEntry", Some(("Problem.Denied", "Problem.Denied(\"owned state\")")), ), ("faultEntry", Some(("integer arithmetic fault", "item + 1"))), ], ); } #[test] fn map_reduction_preserves_seed_reads_and_argument_failure_order() { check( "map_update.dever", &[ ("verify", None), ( "keyFailure", Some(("Problem.Denied", "Problem.Denied(\"key first\")")), ), ( "valueFault", Some(("integer arithmetic fault", "value + 1")), ), ( "seedFailure", Some(("Problem.Denied", "Problem.Denied(\"key first\")")), ), ], ); } type Expected<'text> = (&'text str, Option<(&'text str, &'text str)>); #[test] fn map_entries_keep_owned_and_borrowed_nested_values() { check("map-values.dever", &[("verify", None)]); } fn check(name: &str, cases: &[Expected<'_>]) { let directory = Directory::new(); let project = Project::load(&fixture().with_file_name(name)).unwrap(); let program = project.check().unwrap(); for &(entry, expected) in cases { let binary = build::build(&program, &project.sources, entry, &directory.0.join(entry)).unwrap(); let output = std::process::Command::new(binary).output().unwrap(); if let Some((message, needle)) = expected { assert!(!output.status.success()); assert!(output.stdout.is_empty()); let stderr = String::from_utf8(output.stderr).unwrap(); let source = &project.sources[0]; let (line, column) = source.position(source.text.find(needle).unwrap()); assert!(stderr.contains(message), "{stderr}"); assert!( stderr.contains(&format!("{name}:{line}:{column}:")), "{stderr}" ); } else { assert!( output.status.success(), "{}", String::from_utf8_lossy(&output.stderr) ); assert_eq!(output.stdout, b"true\n"); } } }