Skip to content

Commit 3872c1f

Browse files
committed
Tests for the codec
1 parent ae1e67d commit 3872c1f

File tree

1 file changed

+52
-1
lines changed

1 file changed

+52
-1
lines changed

src/codec.rs

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ impl TokioCodec for Codec {
2525
type In = Message;
2626
type Out = Message;
2727
fn decode(&mut self, buf: &mut EasyBuf) -> IoResult<Option<Message>> {
28-
// TODO: Use object boundary instead of newlines
28+
// TODO: Use object boundary instead of newlines. This waits for
29+
// https://github.com/serde-rs/json/pull/212 or for being able to
30+
// distinguish EOF errors from the others for the trick in
31+
// https://github.com/serde-rs/json/issues/183.
2932
if let Some(i) = buf.as_slice().iter().position(|&b| b == b'\n') {
3033
let line = buf.drain_to(i);
3134
buf.drain_to(1);
@@ -40,3 +43,51 @@ impl TokioCodec for Codec {
4043
Ok(())
4144
}
4245
}
46+
47+
#[cfg(test)]
48+
mod tests {
49+
use super::*;
50+
51+
#[test]
52+
fn encode() {
53+
let mut output = Vec::new();
54+
let mut codec = Codec;
55+
codec.encode(Message::notification("notif".to_owned(), None), &mut output).unwrap();
56+
assert_eq!(Vec::from(&b"{\"jsonrpc\":\"2.0\",\"method\":\"notif\"}\n"[..]), output);
57+
}
58+
59+
#[test]
60+
fn decode() {
61+
fn one(input: &[u8], rest: &[u8]) -> IoResult<Option<Message>> {
62+
let mut codec = Codec;
63+
let mut buf = EasyBuf::new();
64+
buf.get_mut().extend_from_slice(input);
65+
let result = codec.decode(&mut buf);
66+
assert_eq!(rest, buf.as_slice());
67+
result
68+
}
69+
70+
// TODO: We currently have to terminate the records by newline, but that's a temporary
71+
// problem. Once that is solved, have some tests without the newline as well. Also, test
72+
// some messages that don't have a newline, but have a syntax error, so we know we abort
73+
// soon enough.
74+
75+
let notif = Message::notification("notif".to_owned(), None);
76+
let msgstring = Vec::from(&b"{\"jsonrpc\":\"2.0\",\"method\":\"notif\"}\n"[..]);
77+
// A single message, nothing is left
78+
assert_eq!(one(&msgstring, b"").unwrap(), Some(notif.clone()));
79+
// The first message is decoded, the second stays in the buffer
80+
let mut twomsgs = msgstring.clone();
81+
twomsgs.extend_from_slice(&msgstring);
82+
assert_eq!(one(&twomsgs, &msgstring).unwrap(), Some(notif.clone()));
83+
// The second message is incomplete, but stays there
84+
let incomplete = Vec::from(&br#"{"jsonrpc": "2.0", "method":""#[..]);
85+
let mut oneandhalf = msgstring.clone();
86+
oneandhalf.extend_from_slice(&incomplete);
87+
assert_eq!(one(&oneandhalf, &incomplete).unwrap(), Some(notif.clone()));
88+
// An incomplete message ‒ nothing gets out and everything stays
89+
assert_eq!(one(&incomplete, &incomplete).unwrap(), None);
90+
// A syntax error is reported as an error (and eaten, but that's no longer interesting)
91+
assert!(one(b"{]\n", b"").is_err());
92+
}
93+
}

0 commit comments

Comments
 (0)