Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,149 @@
|
||||
use dever::compiler::format;
|
||||
use dever::syntax::source::Source;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[test]
|
||||
fn format_keeps_literals_comments_groups_and_field_order() {
|
||||
let text = "# leading\nmain( ) (answer: Int) {\n answer=(1+2)*3 # same line\n}\n";
|
||||
let source = Source::new(0, "case.dever", text.into());
|
||||
let output = format::format(&source).unwrap();
|
||||
assert_eq!(
|
||||
output,
|
||||
"# leading\nmain() (answer: Int) {\n answer = (1 + 2) * 3 # same line\n}\n"
|
||||
);
|
||||
assert_eq!(
|
||||
format::format(&Source::new(0, "case.dever", output.clone())).unwrap(),
|
||||
output
|
||||
);
|
||||
let literals = Source::new(
|
||||
0,
|
||||
"case.dever",
|
||||
"main() (answer: Text) { answer=\"# \\u{41} \\\"\" }\n".into(),
|
||||
);
|
||||
assert!(
|
||||
format::format(&literals)
|
||||
.unwrap()
|
||||
.contains("\"# \\u{41} \\\"\"")
|
||||
);
|
||||
let fields = Source::new(
|
||||
0,
|
||||
"case.dever",
|
||||
"main() (answer: Item) { answer=Item { second=2, first=1 } }\n".into(),
|
||||
);
|
||||
assert!(
|
||||
format::format(&fields)
|
||||
.unwrap()
|
||||
.contains("second = 2, first = 1")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn format_preserves_crlf() {
|
||||
let text = "main( ) (answer: Int) {\r\n answer=1\r\n}\r\n";
|
||||
let output = format::format(&Source::new(0, "case.dever", text.into())).unwrap();
|
||||
assert_eq!(
|
||||
output,
|
||||
text.replace("main( )", "main()")
|
||||
.replace(" answer=1", " answer = 1")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn format_preserves_local_type_annotations() {
|
||||
let source = Source::new(
|
||||
0,
|
||||
"case.dever",
|
||||
"main() () { value:List<Int?>=[null,1] }".into(),
|
||||
);
|
||||
let formatted = format::format(&source).unwrap();
|
||||
assert!(
|
||||
formatted.contains("value: List<Int?> = [null, 1]"),
|
||||
"{formatted}"
|
||||
);
|
||||
assert_eq!(
|
||||
format::format(&Source::new(0, "case.dever", formatted.clone())).unwrap(),
|
||||
formatted
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn format_preserves_text_policy_and_camel_functions() {
|
||||
let input = "type Category { name: Text(1,80)\ncode: Text lower unique\nbody: Text raw\nnote: Text? upper }\nreadName(input_value: Text) (output_value: Text) { output_value = input_value }";
|
||||
let output = format::format(&Source::new(0, "model.dever", input.into())).unwrap();
|
||||
for preserved in [
|
||||
"code: Text lower unique",
|
||||
"body: Text raw",
|
||||
"note: Text? upper",
|
||||
"readName(input_value: Text)",
|
||||
] {
|
||||
assert!(output.contains(preserved), "{output}");
|
||||
}
|
||||
assert_eq!(
|
||||
format::format(&Source::new(0, "model.dever", output.clone())).unwrap(),
|
||||
output
|
||||
);
|
||||
}
|
||||
|
||||
struct Directory(PathBuf);
|
||||
|
||||
impl Directory {
|
||||
fn new() -> Self {
|
||||
let path = std::env::temp_dir().join(format!(
|
||||
"dever-format-{}-{}",
|
||||
std::process::id(),
|
||||
std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_nanos()
|
||||
));
|
||||
std::fs::create_dir(&path).unwrap();
|
||||
Self(path)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Directory {
|
||||
fn drop(&mut self) {
|
||||
let _ = std::fs::remove_dir_all(&self.0);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn project_prepares_module_and_tests_before_any_rewrite() {
|
||||
let directory = Directory::new();
|
||||
std::fs::create_dir(directory.0.join("module")).unwrap();
|
||||
std::fs::create_dir(directory.0.join("test")).unwrap();
|
||||
let module = directory.0.join("module/main.dever");
|
||||
let test = directory.0.join("test/main.dever");
|
||||
let input = "main( ) () {}\n";
|
||||
std::fs::write(&module, input).unwrap();
|
||||
std::fs::write(&test, "main( {").unwrap();
|
||||
assert!(format::project(&directory.0, false).is_err());
|
||||
assert_eq!(std::fs::read_to_string(&module).unwrap(), input);
|
||||
std::fs::write(&test, input).unwrap();
|
||||
let report = format::project(&directory.0, true).unwrap();
|
||||
assert_eq!(report.checked, 2);
|
||||
assert_eq!(report.changed.len(), 2);
|
||||
assert_eq!(std::fs::read_to_string(&module).unwrap(), input);
|
||||
format::project(&directory.0, false).unwrap();
|
||||
assert!(
|
||||
format::project(&directory.0, true)
|
||||
.unwrap()
|
||||
.changed
|
||||
.is_empty()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn project_rejects_links_without_touching_their_target() {
|
||||
let directory = Directory::new();
|
||||
let target = directory.0.join("actual.dever");
|
||||
std::fs::write(&target, "main( ) () {}\n").unwrap();
|
||||
std::os::unix::fs::symlink(&target, directory.0.join("link.dever")).unwrap();
|
||||
assert!(
|
||||
format::project(&directory.0, false)
|
||||
.unwrap_err()
|
||||
.contains("links")
|
||||
);
|
||||
assert_eq!(std::fs::read_to_string(target).unwrap(), "main( ) () {}\n");
|
||||
}
|
||||
Reference in new issue
Block a user