Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,145 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn enums_and_local_decode_use_shared_cmd_http_and_json_codecs() {
|
||||
let directory = Directory::new();
|
||||
let root = directory.0.join("module/demo/input");
|
||||
std::fs::create_dir_all(root.join("app")).unwrap();
|
||||
std::fs::write(root.join("app/read.dever"), r#"type State { Ready
|
||||
Busy }
|
||||
type Packet { state: State
|
||||
optional: State?
|
||||
states: List<State>
|
||||
payload: Json }
|
||||
type Decoded { Ready(value: Packet)
|
||||
error Invalid(cause: dever.json.JsonResult) }
|
||||
echo(value: State) (output: State) { output = value }
|
||||
packet(value: Packet) (output: Packet) { output = value }
|
||||
decode(payload: Json) (output: Packet) {
|
||||
value: Packet = dever.json.decode(payload)
|
||||
output = value
|
||||
}
|
||||
capture(payload: Json) (valid: Bool) {
|
||||
value: Decoded = result(dever.json.decode(payload))
|
||||
valid = accepted(value)
|
||||
}
|
||||
accepted(value: Decoded.Ready(packet)) (valid: Bool) recover("无效输入返回 false") { valid = packet.state == State.Ready }
|
||||
accepted(value: Decoded.Invalid(cause)) (valid: Bool) recover("无效输入返回 false") { valid = false }
|
||||
encode(value: State) (output: Json) { output = dever.json.encode(value) }
|
||||
fault(divisor: Int) (valid: Bool) {
|
||||
value: Decoded = result(dever.json.decode(dever.json.encode(10 // divisor)))
|
||||
valid = accepted(value)
|
||||
}
|
||||
"#).unwrap();
|
||||
std::fs::write(root.join("api.dever"), "cmd echo = app.echo\ncmd packet = app.packet\ncmd decode = app.decode\ncmd capture = app.capture\ncmd encode = app.encode\ncmd fault = app.fault\npublic get echo = app.echo\npublic post packet = app.packet\npublic post decode = app.decode\npublic post capture = app.capture\n").unwrap();
|
||||
let project = Project::load(&directory.0).unwrap();
|
||||
let program = project.check().unwrap();
|
||||
let binary =
|
||||
build::build(&program, &project.sources, "main", &directory.0.join("app")).unwrap();
|
||||
let packet = r#"{"state":"Ready","optional":null,"states":["Busy"],"payload":{"x":1}}"#;
|
||||
for (name, input, data) in [
|
||||
("echo", r#"{"value":"Ready"}"#.to_owned(), r#""Ready""#),
|
||||
("packet", format!(r#"{{"value":{packet}}}"#), packet),
|
||||
("decode", format!(r#"{{"payload":{packet}}}"#), packet),
|
||||
("capture", format!(r#"{{"payload":{packet}}}"#), "true"),
|
||||
(
|
||||
"capture",
|
||||
r#"{"payload":{"state":"Wrong"}}"#.into(),
|
||||
"false",
|
||||
),
|
||||
("encode", r#"{"value":"Busy"}"#.into(), r#""Busy""#),
|
||||
] {
|
||||
let output = execute(&binary, &format!("demo.input.{name}"), &input);
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"{name}: {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
assert_eq!(
|
||||
String::from_utf8(output.stdout).unwrap(),
|
||||
format!("{{\"code\":0,\"message\":\"ok\",\"data\":{data}}}\n")
|
||||
);
|
||||
}
|
||||
for input in [
|
||||
r#"{"value":"Wrong"}"#,
|
||||
r#"{"value":0}"#,
|
||||
r#"{"value":{"Ready":null}}"#,
|
||||
] {
|
||||
assert!(!execute(&binary, "demo.input.echo", input).status.success());
|
||||
}
|
||||
let fault = execute(&binary, "demo.input.fault", r#"{"divisor":0}"#);
|
||||
assert!(!fault.status.success());
|
||||
let error = String::from_utf8_lossy(&fault.stderr);
|
||||
assert!(error.contains("integer arithmetic fault"), "{error}");
|
||||
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
|
||||
let port = listener.local_addr().unwrap().port();
|
||||
drop(listener);
|
||||
let config = directory.0.join("setting.json");
|
||||
std::fs::write(&config, format!(r#"{{"http":{{"host":"127.0.0.1","port":{port}}},"sites":{{"public":{{"path":"","hosts":["fixture.test"]}}}}}}"#)).unwrap();
|
||||
let mut server = Server(
|
||||
Command::new(&binary)
|
||||
.args(["--config", config.to_str().unwrap()])
|
||||
.stdout(std::process::Stdio::null())
|
||||
.spawn()
|
||||
.unwrap(),
|
||||
);
|
||||
let deadline = Instant::now() + Duration::from_secs(5);
|
||||
while TcpStream::connect(("127.0.0.1", port)).is_err() {
|
||||
assert!(server.0.try_wait().unwrap().is_none());
|
||||
assert!(Instant::now() < deadline);
|
||||
std::thread::sleep(Duration::from_millis(10));
|
||||
}
|
||||
for (method, path, body, status, data) in [
|
||||
(
|
||||
"GET",
|
||||
"/demo/input/echo?value=Busy",
|
||||
"".into(),
|
||||
200,
|
||||
r#""Busy""#,
|
||||
),
|
||||
(
|
||||
"GET",
|
||||
"/demo/input/echo?value=Wrong",
|
||||
"".into(),
|
||||
400,
|
||||
"null",
|
||||
),
|
||||
(
|
||||
"POST",
|
||||
"/demo/input/packet",
|
||||
format!(r#"{{"value":{packet}}}"#),
|
||||
200,
|
||||
packet,
|
||||
),
|
||||
(
|
||||
"POST",
|
||||
"/demo/input/decode",
|
||||
format!(r#"{{"payload":{packet}}}"#),
|
||||
200,
|
||||
packet,
|
||||
),
|
||||
(
|
||||
"POST",
|
||||
"/demo/input/capture",
|
||||
r#"{"payload":null}"#.into(),
|
||||
200,
|
||||
"false",
|
||||
),
|
||||
] {
|
||||
let (actual, output) = request(
|
||||
port,
|
||||
method,
|
||||
path,
|
||||
"fixture.test",
|
||||
"Content-Type: application/json\r\n",
|
||||
&body,
|
||||
);
|
||||
assert_eq!(actual, status, "{path}: {output}");
|
||||
if status == 200 {
|
||||
assert_eq!(
|
||||
output,
|
||||
format!("{{\"code\":0,\"message\":\"ok\",\"data\":{data}}}")
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user