core: Add extra test cases for Number function and resolve the issues they highlight

This commit is contained in:
Will Brindle 2019-10-14 16:30:17 +01:00
parent 463d0fc352
commit 3fa198d8f2
2 changed files with 28 additions and 6 deletions

View File

@ -114,6 +114,7 @@ pub fn create_globals<'gc>(gc_context: MutationContext<'gc, '_>) -> Object<'gc>
} }
#[cfg(test)] #[cfg(test)]
#[allow(clippy::unreadable_literal)]
mod tests { mod tests {
use super::*; use super::*;
use crate::avm1::activation::Activation; use crate::avm1::activation::Activation;
@ -225,6 +226,8 @@ mod tests {
&[Value::String("100a".to_string())] => Value::Bool(true), &[Value::String("100a".to_string())] => Value::Bool(true),
&[Value::String("0x10".to_string())] => Value::Bool(false), &[Value::String("0x10".to_string())] => Value::Bool(false),
&[Value::String("0xhello".to_string())] => Value::Bool(true), &[Value::String("0xhello".to_string())] => Value::Bool(true),
&[Value::String("0x1999999981ffffff".to_string())] => Value::Bool(false),
&[Value::String("0xUIXUIDFKHJDF012345678".to_string())] => Value::Bool(true),
&[Value::String("123e-1".to_string())] => Value::Bool(false), &[Value::String("123e-1".to_string())] => Value::Bool(false),
&[] => Value::Bool(true) &[] => Value::Bool(true)
); );
@ -248,7 +251,8 @@ mod tests {
&[Value::String("0x10".to_string())] => Value::Number(16.0), &[Value::String("0x10".to_string())] => Value::Number(16.0),
&[Value::String("0xhello".to_string())] => Value::Number(std::f64::NAN), &[Value::String("0xhello".to_string())] => Value::Number(std::f64::NAN),
&[Value::String("123e-1".to_string())] => Value::Number(12.3), &[Value::String("123e-1".to_string())] => Value::Number(12.3),
&[Value::String("0x1999999981ffffff".to_string())] => Value::Number(-2113929217.0),
&[Value::String("0xUIXUIDFKHJDF012345678".to_string())] => Value::Number(std::f64::NAN),
&[] => Value::Number(0.0) &[] => Value::Number(0.0)
); );
} }

View File

@ -75,13 +75,31 @@ impl<'gc> Value<'gc> {
Value::Number(v) => *v, Value::Number(v) => *v,
Value::String(v) => match v.as_str() { Value::String(v) => match v.as_str() {
v if v.starts_with("0x") => { v if v.starts_with("0x") => {
let parsed = i64::from_str_radix(&v[2..], 16); let mut n: u32 = 0;
if parsed.is_ok() { for c in v[2..].bytes() {
parsed.unwrap_or_default() as f64 n = n.wrapping_shl(4);
} else { n |= match c {
std::f64::NAN b'0' => 0,
b'1' => 1,
b'2' => 2,
b'3' => 3,
b'4' => 4,
b'5' => 5,
b'6' => 6,
b'7' => 7,
b'8' => 8,
b'9' => 9,
b'a' | b'A' => 10,
b'b' | b'B' => 11,
b'c' | b'C' => 12,
b'd' | b'D' => 13,
b'e' | b'E' => 14,
b'f' | b'F' => 15,
_ => return NAN,
} }
} }
f64::from(n as i32)
}
"" => 0.0, "" => 0.0,
_ => v.parse().unwrap_or(NAN), _ => v.parse().unwrap_or(NAN),
}, },