More tests

This commit is contained in:
Timothy Warren 2020-02-10 15:16:46 -05:00
parent 45e888291c
commit 5ab5dd2e1b

View File

@ -130,17 +130,21 @@ impl JSON {
// if it is not '}', // if it is not '}',
// we take the path of string -> whitespace -> ':' -> value -> ... // we take the path of string -> whitespace -> ':' -> value -> ...
while self.chars[self.i] != '}' { while self.chars[self.i] != '}' {
self.skip_whitespace();
if initial == false { if initial == false {
self.eat(',')?; self.eat(',')?;
self.skip_whitespace(); self.skip_whitespace();
} }
self.skip_whitespace();
let key = match self.parse_string()? { let key = match self.parse_string()? {
Some(value) => match value { Some(value) => match value {
JSONValue::String(s) => s, JSONValue::String(s) => s,
_ => panic!("parse_string returned non-string value"), _ => panic!("parse_string returned non-string value"),
}, },
None => String::new(), None => panic!("Missing object key"),
}; };
self.skip_whitespace(); self.skip_whitespace();
@ -171,6 +175,8 @@ impl JSON {
let mut initial = true; let mut initial = true;
while self.chars[self.i] != ']' { while self.chars[self.i] != ']' {
self.skip_whitespace();
if initial == false { if initial == false {
self.eat(',')?; self.eat(',')?;
} }
@ -237,20 +243,21 @@ impl JSON {
self.increment(1); self.increment(1);
} }
self.increment(1); self.eat('"')?;
Ok(Some(JSONValue::String(result))) Ok(Some(JSONValue::String(result)))
} }
/// See if there's a `JSONValue::Number` next in the JSON /// See if there's a `JSONValue::Number` next in the JSON
fn parse_number(&mut self) -> Result<Option<JSONValue>, ParseError> { fn parse_number(&mut self) -> Result<Option<JSONValue>, ParseError> {
let start = self.i;
// If it doesn't start with 0-9 or a minus sign, it's probably not a number // If it doesn't start with 0-9 or a minus sign, it's probably not a number
if ! (self.chars[self.i].is_ascii_digit() || self.chars[self.i] == '-') { if ! (self.chars[start].is_ascii_digit() || self.chars[start] == '-') {
return Ok(None); return Ok(None);
} }
// All this looping basically just counts the number of characters in the number // All this looping basically just counts the number of characters in the number
let start = self.i;
let max = self.chars.len() - 1; let max = self.chars.len() - 1;
let mut n = start; let mut n = start;
@ -279,7 +286,8 @@ impl JSON {
if self.chars[n] == '-' || self.chars[n] == '+' && n < max { if self.chars[n] == '-' || self.chars[n] == '+' && n < max {
n += 1; n += 1;
} }
// expect digit
// Exponent base
while self.chars[n].is_ascii_digit() && n < max { while self.chars[n].is_ascii_digit() && n < max {
n += 1; n += 1;
} }
@ -459,8 +467,10 @@ mod tests {
fn parse_object() { fn parse_object() {
let mut parser = JSON::new(r#"{"foo": "bar"}"#); let mut parser = JSON::new(r#"{"foo": "bar"}"#);
let result = JSON::parse_object(&mut parser); let result = JSON::parse_object(&mut parser);
let mut hash_map: HashMap<String, JSONValue> = HashMap::new(); let mut hash_map: HashMap<String, JSONValue> = HashMap::new();
hash_map.insert(String::from("foo"), JSONValue::String(String::from("bar"))); hash_map.insert(String::from("foo"), JSONValue::String(String::from("bar")));
assert_eq!(result, Ok(Some(JSONValue::Object(hash_map)))); assert_eq!(result, Ok(Some(JSONValue::Object(hash_map))));
} }
@ -485,13 +495,20 @@ mod tests {
// Number array // Number array
let res = JSON::parse("[1, 2, 3]"); let res = JSON::parse("[1, 2, 3]");
assert_eq!(res, Ok(JSONValue::Array(vec![JSONValue::Number(1f64), JSONValue::Number(2f64), JSONValue::Number(3f64)]))); assert_eq!(res, Ok(JSONValue::Array(vec![JSONValue::Number(1f64), JSONValue::Number(2f64), JSONValue::Number(3f64)])));
// Object array
let result = JSON::parse("[{}]");
assert_eq!(result, Ok(JSONValue::Array(vec![JSONValue::Object(HashMap::new())])));
}
#[test]
fn parse_nested_object() {
let res = JSON::parse(r#"{"a": {"b": []}}"#);
assert!(res.is_ok(), format!("{:#?}", res));
} }
#[test] #[test]
fn can_parse_arbitrary_json() { fn can_parse_arbitrary_json() {
let result = JSON::parse("[{}]");
assert_eq!(result, Ok(JSONValue::Array(vec![JSONValue::Object(HashMap::new())])));
let result = JSON::parse( let result = JSON::parse(
r#"[{ r#"[{
"a": 9.38083151965, "a": 9.38083151965,