Skip to content

Commit

Permalink
Feat/test 262 options (#10)
Browse files Browse the repository at this point in the history
* feat: test 262 options

* test: passed case 4576

* feat: test262
  • Loading branch information
echosoar authored Mar 18, 2023
1 parent e0d9c5e commit dc4ed1e
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 22 deletions.
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ edition = "2021"
[dev-dependencies]
serde = { version = "1.0.126", features = ["derive"]}
serde_json = "1.0.64"
yaml-rust = "0.4"
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
JSI is a JavaScript Interpreter written in Rust.


<img src="https://img.shields.io/badge/Test262-344-brightgreen.svg" alt="test262 passed" />
<img src="https://img.shields.io/badge/Test262-3557%20Passed-brightgreen.svg" alt="test262 passed" />

---
### Usage
Expand Down
12 changes: 12 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ pub enum JSIErrorType {
Unknown,
}

impl JSIErrorType {
pub fn to_string(&self) -> String {
match self {
JSIErrorType::SyntaxError => String::from("SyntaxError"),
JSIErrorType::TypeError => String::from("TypeError"),
JSIErrorType::ReferenceError => String::from("ReferenceError"),
JSIErrorType::RangeError => String::from("RangeError"),
JSIErrorType::Unknown => String::from("Unknown"),
}
}
}

#[derive(Debug, Clone)]
pub struct JSIError {
pub error_type: JSIErrorType,
Expand Down
28 changes: 23 additions & 5 deletions tests/string_test.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use jsi::{JSI, value::Value};
use yaml_rust::YamlLoader;

#[test]
fn run_string() {
Expand All @@ -24,10 +25,27 @@ fn run_string_object() {

#[test]
fn run_xxx() {
let mut jsi = JSI::new();
let result = jsi.run(String::from("\
do function g() {} while (false)
"));
println!("result: {:?}", result)
// let mut jsi = JSI::new();
// let result = jsi.run(String::from("\
// do function g() {} while (false)
// "));
// println!("result: {:?}", result)
let s ="
description: redeclaration with AsyncGeneratorDeclaration (AsyncFunctionDeclaration in BlockStatement)
esid: sec-block-static-semantics-early-errors
features: [async-iteration, async-functions]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
Block : { StatementList }
It is a Syntax Error if the LexicallyDeclaredNames of StatementList contains
any duplicate entries.
";
let docs = YamlLoader::load_from_str(s).unwrap();
println!("{:?}", docs[0]["negativex"]);
}

101 changes: 85 additions & 16 deletions tests/test262_test.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::{path::{Path}, env, fs::{self, File}, io::{Write, Read}, panic};
use std::{path::{Path, PathBuf}, env, fs::{self, File}, io::{Write, Read}, panic};
use std::fs::metadata;
use std::collections::HashMap;
use jsi::JSI;
use serde::{Serialize, Deserialize};
use yaml_rust::{YamlLoader, Yaml};

#[derive(Clone)]
struct Test262Dir {
Expand All @@ -23,8 +24,8 @@ impl Test262Dir {
result: Test262DirResult::new(),
}
}
pub fn run(&mut self, preload_code: &str) {
let (dirs, files) = self.get_childs();
pub fn run(&mut self, preload_code: &str, ignore_list: &Vec<PathBuf>, only_list: &Vec<PathBuf>) {
let (dirs, files) = self.get_childs(ignore_list, only_list);
self.cases += files.len();
for file in files.iter() {
let mut passed = false;
Expand All @@ -33,16 +34,28 @@ impl Test262Dir {
// println!("run: {:?}", code);
let result = jsi.run(format!("{}\n{}", preload_code, file.code));
// println!("result: {:?}", result);
if let Ok(_) = result {
return true;
}
return false
return result;
});
if result.is_err() {
println!("panic: {:?} {:?}", file.name, file.code);
passed = false;
} else {
if let Ok(exec_passed) = result {
passed = exec_passed;
if let Ok(inner_result) = result {
if let Err(jsi_error) = inner_result {
if file.negative {
let error = jsi_error.error_type.to_string();
if file.negative_type.len() > 0 && error != file.negative_type {
println!("negative error type: {:?} {:?} {:?}", file.name, file.negative_type, error);
passed = false;
} else {
passed = true;
}
} else {
passed = false;
}
} else {
passed = !file.negative;
}
}
}
if passed {
Expand All @@ -52,7 +65,7 @@ impl Test262Dir {
}
for dirs in dirs.iter() {
let mut dirs_info = dirs.clone();
dirs_info.run(preload_code);
dirs_info.run(preload_code, ignore_list, only_list);
self.cases += dirs_info.cases;
self.passed += dirs_info.passed;
self.result.dirs.insert(dirs_info.name.clone(), dirs_info.result);
Expand All @@ -61,10 +74,8 @@ impl Test262Dir {
self.result.passed = self.passed;
}

fn get_childs(&self) -> (Vec<Test262Dir>, Vec<Test262File>) {
let dir = Path::new(
&env::current_dir().unwrap()
).join(&self.dir);
fn get_childs(&self, ignore_list: &Vec<PathBuf>, only_list: &Vec<PathBuf>) -> (Vec<Test262Dir>, Vec<Test262File>) {
let dir = make_dir(&self.dir);
let paths = fs::read_dir(&dir).unwrap();
let names = paths.filter_map(|entry| {
entry.ok().and_then(|e|
Expand All @@ -76,6 +87,20 @@ impl Test262Dir {
let mut files: Vec<Test262File> = vec![];
for name in names.iter() {
let abso_name = dir.join(&name);
if only_list.len() > 0 {
let mut is_ignore = true;
for only in only_list.iter() {
if abso_name.starts_with(&only) {
is_ignore = false
}
}
if is_ignore {
continue;
}
}
if ignore_list.contains(&abso_name) {
continue;
}
let md = metadata(&abso_name).unwrap();
if md.is_dir() {
dirs.push(Test262Dir::new(name.clone(), String::from(abso_name.to_str().unwrap())))
Expand All @@ -89,23 +114,54 @@ impl Test262Dir {
}
}



#[derive(Clone)]
struct Test262File {
pub name: String,
pub code: String,
pub negative: bool,
pub negative_type: String,

}
impl Test262File {
pub fn new(name: String, path: String) -> Test262File {
let mut file = File::open(&path).unwrap();
let mut code = String::new();
file.read_to_string(&mut code).unwrap();
// TODO: negative in-statement-position-if-expression-statement.js
let config = Test262File::parse(&code);
return Test262File {
name,
code,
negative: config.0,
negative_type: config.1
}
}

pub fn parse(code: &String) -> (bool, String) {
let mut negative = false;
let mut negative_type = String::from("");
let start = code.find("/*---");
if let Some(start) = start {
let end = code.find("---*/");
if let Some(end) = end {
let config = &code[start + 5..end];
let docs = YamlLoader::load_from_str(config);
if let Ok(docs) = docs {
if let Yaml::BadValue = docs[0]["negative"] {

} else {
negative = true;
let negative_type_value = docs[0]["negative"]["type"].as_str();
if let Some(negative_type_item) = negative_type_value {
negative_type = String::from(negative_type_item);
}
}
}
}
}
return (negative, negative_type);
}
}

#[derive(Clone,Serialize, Deserialize, Debug)]
Expand Down Expand Up @@ -134,11 +190,24 @@ fn load_harness(path: &str) -> String {
return code;
}

fn make_dir(dir: &String) -> PathBuf {
Path::new(
&env::current_dir().unwrap()
).join(dir)
}

#[test]
fn test_all_262() {
let prelaod = format!("{}\n", load_harness("harness/assert.js"));
let ignore_list: Vec<PathBuf> =vec![
make_dir(&String::from("test262/test/annexB")),
make_dir(&String::from("test262/test/intl402")),
];
let only_list: Vec<PathBuf> =vec![
// make_dir(&String::from("test262/test/language")),
];
let mut test262 = Test262Dir::new(String::from("base"), String::from("test262/test"));
test262.run(prelaod.as_str());
test262.run(prelaod.as_str(), &ignore_list, &only_list);
let serialized_result = serde_json::to_string_pretty(&test262.result).unwrap();
let file_name = "./262_result.json";
let mut file = File::create(file_name).unwrap();
Expand Down

0 comments on commit dc4ed1e

Please sign in to comment.