mod api; mod archive; #[cfg(target_os = "linux")] mod cache; mod commands; mod documentation; mod fixture; mod library; mod lock; mod npm; mod worker; use fixture::{Fixture, app, command, write}; #[test] fn locked_sources_build_native_with_transitive_calls_and_original_locations() { let mut fixture = Fixture::new(&["numbers@^1"]); fixture.package( "numbers", &[("units", "^1")], &[( "module/numbers/value/app.dever", &app("units.value.value(input) * 2"), )], ); fixture.package( "units", &[], &[("module/units/value/app.dever", &app("input + 1"))], ); write( &fixture.directory.0, "module/demo/value/app.dever", app("numbers.value.value(input)"), ); write( &fixture.directory.0, "module/demo/value/api.dever", command(), ); let before = std::fs::read(fixture.directory.0.join("dever.lock")).unwrap(); let project = fixture.load().unwrap(); let program = project.check().unwrap(); let binary = dever::compiler::build::build( &program, &project.sources, "main", &fixture.directory.0.join("app"), ) .unwrap(); let result = std::process::Command::new(&binary) .args(["demo.value.value", "{\"input\":20}"]) .output() .unwrap(); assert!( result.status.success(), "{}", String::from_utf8_lossy(&result.stderr) ); assert_eq!( result.stdout, b"{\"code\":0,\"message\":\"ok\",\"data\":42}\n" ); let result = std::process::Command::new(binary) .args(["demo.value.value", "{\"input\":9223372036854775807}"]) .output() .unwrap(); assert!(!result.status.success()); assert!( String::from_utf8_lossy(&result.stderr).contains("package/module/units/value/app.dever:") ); assert_eq!( before, std::fs::read(fixture.directory.0.join("dever.lock")).unwrap() ); assert!(!fixture.directory.0.join("module/numbers").exists()); assert!(!fixture.directory.0.join("package").exists()); } #[test] fn package_only_project_and_local_sources_share_identity_and_layout_checks() { let mut fixture = Fixture::new(&["numbers@1.0.0"]); fixture.package( "numbers", &[], &[ ("module/numbers/value/app.dever", &app("input + 1")), ("module/numbers/value/api.dever", &command()), ("module/numbers/assets/home.html", "

resource

"), ], ); assert!(!fixture.directory.0.join("module").exists()); let project = fixture.load().unwrap(); let program = project.check().unwrap(); assert_eq!(program.commands[0].name, "numbers.value.value"); write( &fixture.directory.0, "module/numbers/unrelated/readme.txt", "local component must win by explicit error", ); fixture.reject("collides with local component"); } #[test] fn package_source_format_and_unimplemented_roles_cannot_bypass_checking() { for (path, text, load_error) in [ ( "module/numbers/value/app.dever.md", app("input"), Some("no Dever source"), ), ( "module/numbers/value/test.dever", app("input"), Some("role 'test' is not implemented yet"), ), ] { let mut fixture = Fixture::new(&["numbers@1.0.0"]); fixture.package("numbers", &[], &[(path, &text)]); fixture.reject(load_error.unwrap()); } } #[test] fn package_roles_allow_a_single_topic_file() { let mut fixture = Fixture::new(&["numbers@1.0.0"]); fixture.package( "numbers", &[], &[ ("module/numbers/value/app/only.dever", &app("input")), ("module/numbers/value/api.dever", &command()), ], ); let project = fixture.load().unwrap(); assert_eq!( project.check().unwrap().commands[0].name, "numbers.value.value" ); }