mirror of https://github.com/boa-dev/boa.git
Paul Lancaster
5 years ago
committed by
GitHub
25 changed files with 756 additions and 69 deletions
@ -0,0 +1,16 @@
|
||||
use super::{Executable, Interpreter, InterpreterState}; |
||||
use crate::{ |
||||
builtins::value::{ResultValue, Value}, |
||||
syntax::ast::node::Break, |
||||
}; |
||||
|
||||
#[cfg(test)] |
||||
mod tests; |
||||
|
||||
impl Executable for Break { |
||||
fn run(&self, interpreter: &mut Interpreter) -> ResultValue { |
||||
interpreter.set_current_state(InterpreterState::Break(self.label().map(String::from))); |
||||
|
||||
Ok(Value::undefined()) |
||||
} |
||||
} |
@ -0,0 +1,17 @@
|
||||
use super::{Interpreter, InterpreterState}; |
||||
use crate::{exec::Executable, syntax::ast::node::Break, Realm}; |
||||
|
||||
#[test] |
||||
fn check_post_state() { |
||||
let realm = Realm::create(); |
||||
let mut engine = Interpreter::new(realm); |
||||
|
||||
let brk: Break = Break::new("label"); |
||||
|
||||
brk.run(&mut engine).unwrap(); |
||||
|
||||
assert_eq!( |
||||
engine.get_current_state(), |
||||
&InterpreterState::Break(Some("label".to_string())) |
||||
); |
||||
} |
@ -0,0 +1,101 @@
|
||||
use crate::exec; |
||||
|
||||
#[test] |
||||
fn while_loop_late_break() { |
||||
// Ordering with statement before the break.
|
||||
let scenario = r#" |
||||
let a = 1; |
||||
while (a < 5) { |
||||
a++; |
||||
if (a == 3) { |
||||
break; |
||||
} |
||||
} |
||||
a; |
||||
"#; |
||||
|
||||
assert_eq!(&exec(scenario), "3"); |
||||
} |
||||
|
||||
#[test] |
||||
fn while_loop_early_break() { |
||||
// Ordering with statements after the break.
|
||||
let scenario = r#" |
||||
let a = 1; |
||||
while (a < 5) { |
||||
if (a == 3) { |
||||
break; |
||||
} |
||||
a++; |
||||
} |
||||
a; |
||||
"#; |
||||
|
||||
assert_eq!(&exec(scenario), "3"); |
||||
} |
||||
|
||||
#[test] |
||||
fn for_loop_break() { |
||||
let scenario = r#" |
||||
let a = 1; |
||||
for (; a < 5; a++) { |
||||
if (a == 3) { |
||||
break; |
||||
} |
||||
} |
||||
a; |
||||
"#; |
||||
|
||||
assert_eq!(&exec(scenario), "3"); |
||||
} |
||||
|
||||
#[test] |
||||
fn for_loop_return() { |
||||
let scenario = r#" |
||||
function foo() { |
||||
for (let a = 1; a < 5; a++) { |
||||
if (a == 3) { |
||||
return a; |
||||
} |
||||
} |
||||
} |
||||
|
||||
foo(); |
||||
"#; |
||||
|
||||
assert_eq!(&exec(scenario), "3"); |
||||
} |
||||
|
||||
#[test] |
||||
fn do_loop_late_break() { |
||||
// Ordering with statement before the break.
|
||||
let scenario = r#" |
||||
let a = 1; |
||||
do { |
||||
a++; |
||||
if (a == 3) { |
||||
break; |
||||
} |
||||
} while (a < 5); |
||||
a; |
||||
"#; |
||||
|
||||
assert_eq!(&exec(scenario), "3"); |
||||
} |
||||
|
||||
#[test] |
||||
fn do_loop_early_break() { |
||||
// Ordering with statements after the break.
|
||||
let scenario = r#" |
||||
let a = 1; |
||||
do { |
||||
if (a == 3) { |
||||
break; |
||||
} |
||||
a++; |
||||
} while (a < 5); |
||||
a; |
||||
"#; |
||||
|
||||
assert_eq!(&exec(scenario), "3"); |
||||
} |
@ -0,0 +1,200 @@
|
||||
use crate::exec; |
||||
|
||||
#[test] |
||||
fn single_case_switch() { |
||||
let scenario = r#" |
||||
let a = 10; |
||||
switch (a) { |
||||
case 10: |
||||
a = 20; |
||||
break; |
||||
} |
||||
|
||||
a; |
||||
"#; |
||||
assert_eq!(&exec(scenario), "20"); |
||||
} |
||||
|
||||
#[test] |
||||
fn no_cases_switch() { |
||||
let scenario = r#" |
||||
let a = 10; |
||||
switch (a) { |
||||
} |
||||
|
||||
a; |
||||
"#; |
||||
assert_eq!(&exec(scenario), "10"); |
||||
} |
||||
|
||||
#[test] |
||||
fn no_true_case_switch() { |
||||
let scenario = r#" |
||||
let a = 10; |
||||
switch (a) { |
||||
case 5: |
||||
a = 15; |
||||
break; |
||||
} |
||||
|
||||
a; |
||||
"#; |
||||
assert_eq!(&exec(scenario), "10"); |
||||
} |
||||
|
||||
#[test] |
||||
fn two_case_switch() { |
||||
let scenario = r#" |
||||
let a = 10; |
||||
switch (a) { |
||||
case 5: |
||||
a = 15; |
||||
break; |
||||
case 10: |
||||
a = 20; |
||||
break; |
||||
} |
||||
|
||||
a; |
||||
"#; |
||||
assert_eq!(&exec(scenario), "20"); |
||||
} |
||||
|
||||
#[test] |
||||
fn two_case_no_break_switch() { |
||||
let scenario = r#" |
||||
let a = 10; |
||||
let b = 10; |
||||
|
||||
switch (a) { |
||||
case 10: |
||||
a = 150; |
||||
case 20: |
||||
b = 150; |
||||
break; |
||||
} |
||||
|
||||
a + b; |
||||
"#; |
||||
assert_eq!(&exec(scenario), "300"); |
||||
} |
||||
|
||||
#[test] |
||||
fn three_case_partial_fallthrough() { |
||||
let scenario = r#" |
||||
let a = 10; |
||||
let b = 10; |
||||
|
||||
switch (a) { |
||||
case 10: |
||||
a = 150; |
||||
case 20: |
||||
b = 150; |
||||
break; |
||||
case 15: |
||||
b = 1000; |
||||
break; |
||||
} |
||||
|
||||
a + b; |
||||
"#; |
||||
assert_eq!(&exec(scenario), "300"); |
||||
} |
||||
|
||||
#[test] |
||||
fn default_taken_switch() { |
||||
let scenario = r#" |
||||
let a = 10; |
||||
|
||||
switch (a) { |
||||
case 5: |
||||
a = 150; |
||||
break; |
||||
default: |
||||
a = 70; |
||||
} |
||||
|
||||
a; |
||||
"#; |
||||
assert_eq!(&exec(scenario), "70"); |
||||
} |
||||
|
||||
#[test] |
||||
fn default_not_taken_switch() { |
||||
let scenario = r#" |
||||
let a = 5; |
||||
|
||||
switch (a) { |
||||
case 5: |
||||
a = 150; |
||||
break; |
||||
default: |
||||
a = 70; |
||||
} |
||||
|
||||
a; |
||||
"#; |
||||
assert_eq!(&exec(scenario), "150"); |
||||
} |
||||
|
||||
#[test] |
||||
fn string_switch() { |
||||
let scenario = r#" |
||||
let a = "hello"; |
||||
|
||||
switch (a) { |
||||
case "hello": |
||||
a = "world"; |
||||
break; |
||||
default: |
||||
a = "hi"; |
||||
} |
||||
|
||||
a; |
||||
"#; |
||||
assert_eq!(&exec(scenario), "world"); |
||||
} |
||||
|
||||
#[test] |
||||
fn bigger_switch_example() { |
||||
let expected = ["Mon", "Tue", "Wed", "Thurs", "Fri", "Sat", "Sun"]; |
||||
|
||||
for (i, val) in expected.iter().enumerate() { |
||||
let scenario = format!( |
||||
r#" |
||||
let a = {}; |
||||
let b = "unknown"; |
||||
|
||||
switch (a) {{ |
||||
case 0: |
||||
b = "Mon"; |
||||
break; |
||||
case 1: |
||||
b = "Tue"; |
||||
break; |
||||
case 2: |
||||
b = "Wed"; |
||||
break; |
||||
case 3: |
||||
b = "Thurs"; |
||||
break; |
||||
case 4: |
||||
b = "Fri"; |
||||
break; |
||||
case 5: |
||||
b = "Sat"; |
||||
break; |
||||
case 6: |
||||
b = "Sun"; |
||||
break;
|
||||
}} |
||||
|
||||
b; |
||||
|
||||
"#, |
||||
i |
||||
); |
||||
|
||||
assert_eq!(&exec(&scenario), val); |
||||
} |
||||
} |
@ -1 +1,99 @@
|
||||
use crate::syntax::parser::tests::check_invalid; |
||||
|
||||
/// Checks parsing malformed switch with no closeblock.
|
||||
#[test] |
||||
fn check_switch_no_closeblock() { |
||||
check_invalid( |
||||
r#" |
||||
let a = 10; |
||||
switch (a) { |
||||
case 10: |
||||
a = 20; |
||||
break; |
||||
|
||||
"#, |
||||
); |
||||
} |
||||
|
||||
/// Checks parsing malformed switch in which a case is started but not finished.
|
||||
#[test] |
||||
fn check_switch_case_unclosed() { |
||||
check_invalid( |
||||
r#" |
||||
let a = 10; |
||||
switch (a) { |
||||
case 10: |
||||
a = 20; |
||||
|
||||
"#, |
||||
); |
||||
} |
||||
|
||||
/// Checks parsing malformed switch with 2 defaults.
|
||||
#[test] |
||||
fn check_switch_two_default() { |
||||
check_invalid( |
||||
r#" |
||||
let a = 10; |
||||
switch (a) { |
||||
default: |
||||
a = 20; |
||||
break; |
||||
default: |
||||
a = 30; |
||||
break; |
||||
} |
||||
"#, |
||||
); |
||||
} |
||||
|
||||
/// Checks parsing malformed switch with no expression.
|
||||
#[test] |
||||
fn check_switch_no_expr() { |
||||
check_invalid( |
||||
r#" |
||||
let a = 10; |
||||
switch { |
||||
default: |
||||
a = 20; |
||||
break; |
||||
} |
||||
"#, |
||||
); |
||||
} |
||||
|
||||
/// Checks parsing malformed switch with an unknown label.
|
||||
#[test] |
||||
fn check_switch_unknown_label() { |
||||
check_invalid( |
||||
r#" |
||||
let a = 10; |
||||
switch (a) { |
||||
fake: |
||||
a = 20; |
||||
break; |
||||
} |
||||
"#, |
||||
); |
||||
} |
||||
|
||||
/// Checks parsing malformed switch with two defaults that are seperated by cases.
|
||||
#[test] |
||||
fn check_switch_seperated_defaults() { |
||||
check_invalid( |
||||
r#" |
||||
let a = 10; |
||||
switch (a) { |
||||
default: |
||||
a = 20; |
||||
break; |
||||
case 10: |
||||
a = 60; |
||||
break; |
||||
default: |
||||
a = 30; |
||||
break; |
||||
} |
||||
"#, |
||||
); |
||||
} |
||||
|
Loading…
Reference in new issue