1
use std::{char::from_u32, fmt::Debug};
2

            
3
use ron::{de::from_str, ser::to_string};
4
use serde::{Deserialize, Serialize};
5

            
6
#[test]
7
4
fn test_escape_basic() {
8
4
    assert_eq!(to_string(&"\x07").unwrap(), "\"\\u{7}\"");
9

            
10
4
    assert_eq!(from_str::<String>("\"\\x07\"").unwrap(), "\x07");
11
4
    assert_eq!(from_str::<String>("\"\\u{7}\"").unwrap(), "\x07");
12

            
13
4
    assert_eq!(from_str::<char>("\'\\x07\'").unwrap(), '\x07');
14
4
    assert_eq!(from_str::<char>("\'\\u{7}\'").unwrap(), '\x07');
15

            
16
4
    assert_eq!(
17
4
        from_str::<char>("\'\\u{}\'").unwrap_err(),
18
        ron::error::SpannedError {
19
            code: ron::Error::InvalidEscape("Expected 1-6 digits, got 0 digits in Unicode escape"),
20
            span: ron::error::Span {
21
                start: ron::error::Position { line: 1, col: 4 },
22
                end: ron::error::Position { line: 1, col: 5 },
23
            }
24
        }
25
    );
26

            
27
4
    assert_eq!(
28
4
        from_str::<char>("\'\\q\'").unwrap_err(),
29
        ron::error::SpannedError {
30
            code: ron::Error::InvalidEscape("Unknown escape character"),
31
            span: ron::error::Span {
32
                start: ron::error::Position { line: 1, col: 1 },
33
                end: ron::error::Position { line: 1, col: 4 },
34
            }
35
        }
36
    )
37
4
}
38

            
39
528
fn check_same<T>(t: T)
40
528
where
41
528
    T: Debug + for<'a> Deserialize<'a> + PartialEq + Serialize,
42
{
43
528
    let s: String = to_string(&t).unwrap();
44

            
45
528
    println!("Serialized: \n\n{}\n\n", s);
46

            
47
528
    assert_eq!(from_str(&s), Ok(t));
48
528
}
49

            
50
#[test]
51
4
fn test_ascii_10() {
52
4
    check_same("\u{10}".to_owned());
53
4
}
54

            
55
#[test]
56
4
fn test_ascii_chars() {
57
4
    (1..128).flat_map(from_u32).for_each(check_same)
58
4
}
59

            
60
#[test]
61
4
fn test_ascii_string() {
62
4
    let s: String = (1..128).flat_map(from_u32).collect();
63

            
64
4
    check_same(s);
65
4
}
66

            
67
#[test]
68
4
fn test_non_ascii() {
69
4
    assert_eq!(to_string(&"♠").unwrap(), "\"♠\"");
70
4
    assert_eq!(to_string(&"ß").unwrap(), "\"ß\"");
71
4
    assert_eq!(to_string(&"ä").unwrap(), "\"ä\"");
72
4
    assert_eq!(to_string(&"ö").unwrap(), "\"ö\"");
73
4
    assert_eq!(to_string(&"ü").unwrap(), "\"ü\"");
74
4
}
75

            
76
#[test]
77
4
fn test_chars() {
78
4
    assert_eq!(to_string(&'♠').unwrap(), "'♠'");
79
4
    assert_eq!(to_string(&'ß').unwrap(), "'ß'");
80
4
    assert_eq!(to_string(&'ä').unwrap(), "'ä'");
81
4
    assert_eq!(to_string(&'ö').unwrap(), "'ö'");
82
4
    assert_eq!(to_string(&'ü').unwrap(), "'ü'");
83
4
    assert_eq!(to_string(&'\u{715}').unwrap(), "'\u{715}'");
84
4
    assert_eq!(
85
4
        from_str::<char>("'\u{715}'").unwrap(),
86
4
        from_str("'\\u{715}'").unwrap()
87
    );
88
4
}
89

            
90
#[test]
91
4
fn test_nul_in_string() {
92
4
    assert_eq!(
93
4
        from_str("\"Hello\0World!\""),
94
4
        Ok(String::from("Hello\0World!"))
95
    );
96

            
97
4
    check_same("Hello\0World!".to_owned());
98
4
    check_same("Hello\x00World!".to_owned());
99
4
    check_same("Hello\u{0}World!".to_owned());
100
4
}
101

            
102
#[test]
103
4
fn test_string_continuation_escape() {
104
4
    let cases = [
105
4
        (concat!("\"foo\\", "\n    bar\""), "foobar"),
106
4
        (concat!("\"foo\\", "\n\n    \\nbar\""), "foo\nbar"),
107
4
        (concat!("\"foo\\", "\r\n \tbar\""), "foobar"),
108
4
        (concat!("\"foo\\", "\n\r \tbar\""), "foobar"),
109
4
        (concat!("\"foo\\", "\n\""), "foo"),
110
4
    ];
111

            
112
20
    for (source, expected) in cases {
113
20
        assert_eq!(from_str::<String>(source).unwrap(), expected);
114
    }
115

            
116
8
    for source in [
117
4
        concat!("b\"foo\\", "\n    bar\""),
118
4
        concat!("b\"foo\\", "\r\n    bar\""),
119
4
    ] {
120
8
        let bytes = from_str::<bytes::Bytes>(source).unwrap();
121
8
        assert_eq!(&*bytes, b"foobar");
122
    }
123
4
}
124

            
125
#[test]
126
4
fn test_string_continuation_whitespace_boundary() {
127
4
    let retained = "\u{a0}\u{b}\u{c}\u{85}\u{200e}\u{200f}\u{2028}\u{2029}";
128
4
    let source = ["\"foo\\\n", retained, "bar\""].concat();
129
4
    let expected = ["foo", retained, "bar"].concat();
130

            
131
4
    assert_eq!(from_str::<String>(&source).unwrap(), expected);
132
4
}
133

            
134
#[test]
135
4
fn test_string_continuation_rejected_outside_strings() {
136
8
    for error in [
137
4
        from_str::<char>(concat!("'\\", "\n'")).unwrap_err().code,
138
4
        from_str::<u8>(concat!("b'\\", "\n'")).unwrap_err().code,
139
4
    ] {
140
8
        assert_eq!(error, ron::Error::InvalidEscape("Unknown escape character"));
141
    }
142
4
}
143

            
144
#[test]
145
4
fn test_string_continuation_raw_strings_are_unchanged() {
146
4
    let raw = from_str::<String>(concat!("r\"foo\\", "\n  bar\"")).unwrap();
147
4
    assert_eq!(raw, concat!("foo\\", "\n  bar"));
148

            
149
4
    let raw_bytes = from_str::<bytes::Bytes>(concat!("br\"foo\\", "\n  bar\"")).unwrap();
150
4
    assert_eq!(&*raw_bytes, concat!("foo\\", "\n  bar").as_bytes());
151
4
}
152

            
153
#[test]
154
4
fn test_string_continuation_errors() {
155
4
    assert_eq!(
156
4
        from_str::<String>(concat!("\"foo\\", "\rbar\""))
157
4
            .unwrap_err()
158
            .code,
159
        ron::Error::InvalidEscape("Unknown escape character")
160
    );
161

            
162
4
    assert_eq!(
163
4
        from_str::<String>(concat!("\"foo\\", "\n"))
164
4
            .unwrap_err()
165
            .code,
166
        ron::Error::ExpectedStringEnd
167
    );
168
4
}