Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions funcs.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
CARGO_PROFDATA=$(find $HOME/.rustup -name llvm-profdata)
CARGO_COV=$(find $HOME/.rustup -name llvm-cov)

function objects() {
for file in $( \
LLVM_PROFILE_FILE="res-%m.profraw" RUSTFLAGS="-Cinstrument-coverage" cargo test --profile coverage --no-run --message-format=json 2> /dev/null | \
Expand Down Expand Up @@ -26,7 +29,7 @@ function tst() {
RUST_BACKTRACE=1 LLVM_PROFILE_FILE="res-%m.profraw" RUSTFLAGS="-Cinstrument-coverage" cargo test --bin res --profile coverage $quiet -- "$@"
local covstatus=$?
if [ $covstatus -eq 0 ]; then
cargo profdata -- merge res-*.profraw --output="$output"
$CARGO_PROFDATA merge res-*.profraw --output="$output"
fi
cd $here
return $covstatus
Expand All @@ -37,7 +40,7 @@ function summary() {
cd ~/*/rust-e262
local profile=res.profdata
if [ $# -gt 0 ]; then profile="$1"; fi
cargo cov -- report --use-color --ignore-filename-regex='/rustc/|/\.cargo/|\.rustup/toolchains|/.*tests\.rs|/testhelp\.rs|/tests/' --instr-profile="$profile" $(objects)
$CARGO_COV report --use-color --ignore-filename-regex='/rustc/|/\.cargo/|\.rustup/toolchains|/.*tests\.rs|/testhelp\.rs|/tests/' --instr-profile="$profile" $(objects)
cd $here
}

Expand All @@ -50,7 +53,7 @@ function z() {
function s() {
local here=$(pwd)
cd ~/*/rust-e262
cargo cov -- show \
$CARGO_COV show \
--use-color \
--ignore-filename-regex='/rustc/|/\.cargo/|\.rustup/toolchains|/.*tests\.rs|/testhelp\.rs|/tests/' \
--instr-profile=res.profdata $(objects) \
Expand Down Expand Up @@ -95,7 +98,7 @@ function report() {
shift
done

cargo cov -- show \
$CARGO_COV show \
$color \
--ignore-filename-regex='/rustc/|/\.cargo/|\.rustup/toolchains|/.*tests\.rs|/testhelp\.rs|/tests/' \
--instr-profile="$profile" $(objects) \
Expand Down
64 changes: 64 additions & 0 deletions src/arguments_object/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -638,4 +638,68 @@ mod arguments_object {
none_function!(to_map_obj);
none_function!(to_regexp_object);
none_function!(to_string_obj);

#[test]
fn own_property_keys() {
setup_test_agent();
let obj = make(); // adds 0, 1, 2, and 100

let to_prim = wks(WksId::ToPrimitive);
let species = wks(WksId::Species);

obj.o
.define_own_property(
"60".into(),
PotentialPropertyDescriptor::new().value("q").writable(true).enumerable(true).configurable(true),
)
.unwrap();
obj.o
.define_own_property(
"6".into(),
PotentialPropertyDescriptor::new().value("s").writable(true).enumerable(true).configurable(true),
)
.unwrap();
obj.o
.define_own_property(
"zebra".into(),
PotentialPropertyDescriptor::new().value(0).writable(true).enumerable(true).configurable(true),
)
.unwrap();
obj.o
.define_own_property(
"alpha".into(),
PotentialPropertyDescriptor::new().value(1).writable(true).enumerable(true).configurable(true),
)
.unwrap();
obj.o
.define_own_property(
to_prim.clone().into(),
PotentialPropertyDescriptor::new().value(2).writable(true).enumerable(true).configurable(true),
)
.unwrap();
obj.o
.define_own_property(
species.clone().into(),
PotentialPropertyDescriptor::new().value(3).writable(true).enumerable(true).configurable(true),
)
.unwrap();

let keys = obj.o.own_property_keys().unwrap();

assert_eq!(
keys,
vec![
"0".into(),
"1".into(),
"2".into(),
"6".into(),
"60".into(),
"100".into(),
"zebra".into(),
"alpha".into(),
to_prim.into(),
species.into()
]
);
}
}
18 changes: 4 additions & 14 deletions src/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,18 +412,13 @@ impl fmt::Display for Insn {
/// A compilation might leave a value on the runtime stack that could be a reference. We want to communicate back to the
/// parent compilation step about whether that's possible or not. The values are "Might leave a reference on top of the
/// stack" and "Will never leave a reference on the top of the stack".
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub(crate) enum RefResult {
Maybe,
#[default]
Never,
}

impl Default for RefResult {
fn default() -> Self {
Self::Never
}
}

impl From<bool> for RefResult {
fn from(src: bool) -> Self {
if src { RefResult::Maybe } else { RefResult::Never }
Expand All @@ -433,18 +428,13 @@ impl From<bool> for RefResult {
/// A compilation might leave a value on top of the runtime stack that could be an error. We want to communicate back to
/// the parent compilation step about whether that's possible or not. The values are "Might leave an abrupt completion
/// on top of the stack" and "Will never leave an abrupt completion on top of the stack".
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub(crate) enum AbruptResult {
Maybe,
#[default]
Never,
}

impl Default for AbruptResult {
fn default() -> Self {
Self::Never
}
}

impl From<CompilerStatusFlags> for AbruptResult {
fn from(src: CompilerStatusFlags) -> Self {
src.can_be_abrupt
Expand Down
34 changes: 34 additions & 0 deletions src/compiler/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,12 @@ mod abrupt_result {
fn from(item: impl Into<AbruptResult>) -> AbruptResult {
item.into()
}

#[test_case(AbruptResult::Maybe => CompilerStatusFlags { can_be_abrupt: AbruptResult::Maybe, can_be_reference: RefResult::Never }; "AbruptResult::Maybe")]
#[test_case(AbruptResult::Never => CompilerStatusFlags { can_be_abrupt: AbruptResult::Never, can_be_reference: RefResult::Never }; "AbruptResult::Never")]
fn into_compiiler_status_flags(item: AbruptResult) -> CompilerStatusFlags {
item.into()
}
}

mod always_abrupt_result {
Expand All @@ -422,6 +428,20 @@ mod always_abrupt_result {
let item = AlwaysAbruptResult {};
assert!(item.maybe_abrupt());
}

#[test]
fn into_compiiler_status_flags() {
let item = AlwaysAbruptResult {};
let csf: CompilerStatusFlags = item.into();
assert_eq!(csf, CompilerStatusFlags { can_be_abrupt: AbruptResult::Maybe, can_be_reference: RefResult::Never });
}

#[test]
fn into_abrupt_result() {
let item = AlwaysAbruptResult {};
let ar: AbruptResult = item.into();
assert_eq!(ar, AbruptResult::Maybe);
}
}

mod always_ref_result {
Expand All @@ -439,6 +459,13 @@ mod always_ref_result {
let cloned = item.clone();
assert!(matches!(cloned, AlwaysRefResult {}));
}

#[test]
fn into_compiiler_status_flags() {
let item = AlwaysRefResult {};
let csf: CompilerStatusFlags = item.into();
assert_eq!(csf, CompilerStatusFlags { can_be_abrupt: AbruptResult::Never, can_be_reference: RefResult::Maybe });
}
}

mod always_abrupt_ref_result {
Expand All @@ -456,6 +483,13 @@ mod always_abrupt_ref_result {
let cloned = item.clone();
assert!(matches!(cloned, AlwaysAbruptRefResult {}));
}

#[test]
fn into_compiiler_status_flags() {
let item = AlwaysAbruptRefResult {};
let csf: CompilerStatusFlags = item.into();
assert_eq!(csf, CompilerStatusFlags { can_be_abrupt: AbruptResult::Maybe, can_be_reference: RefResult::Maybe });
}
}

mod never_abrupt_ref_result {
Expand Down
17 changes: 17 additions & 0 deletions src/execution_context/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,23 @@ mod script_or_module {
text.clone()
}

#[test_case(|| {
let mut sr = ScriptRecord::new_empty(current_realm_record().unwrap());
sr.text = String::from("I am a walrus");
ScriptOrModule::Script(Rc::new(sr))
} => "I am a walrus --- "; "script")]
#[test_case(|| ScriptOrModule::Module(Rc::new(ModuleRecord{})) => panics "not yet implemented"; "module")]
fn source_tree(maker: impl FnOnce() -> ScriptOrModule) -> String {
setup_test_agent();
let som = maker();
let tree = som.source_tree();
if let SourceTree { text, ast: ParsedText::Script(script) } = tree {
format!("{text} --- {script}")
} else {
panic!("expected ParsedText::Script, got something else")
}
}

#[test_case(
|| {
let mut sr = ScriptRecord::new_empty(current_realm_record().unwrap());
Expand Down
8 changes: 2 additions & 6 deletions src/object/objtests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1314,17 +1314,13 @@ fn validate_and_apply_property_descriptor_06() {
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ONE BIG TEST to check all different PotentialPropertyDescriptors against all different existing PropertyDescriptors.
// (There are 23,328 different tests included in this.)
#[derive(PartialEq, Eq)]
#[derive(PartialEq, Eq, Default)]
enum Stage {
#[default]
Data,
Accessor,
Done,
}
impl Default for Stage {
fn default() -> Self {
Self::Data
}
}
#[expect(clippy::struct_excessive_bools)]
#[derive(Default)]
struct VAPDIter {
Expand Down
25 changes: 25 additions & 0 deletions src/parser/additive_operators/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,4 +191,29 @@ mod additive_expression {
fn location(src: &str) -> Location {
Maker::new(src).additive_expression().location()
}

#[test_case("a+call()" => false; "add")]
#[test_case("a-call()" => false; "subtract")]
#[test_case("call()" => true; "fall-thru")]
#[test_case("37" => false; "fall-thru, no call")]
fn has_call_in_tail_position(src: &str) -> bool {
let location = find_call(src);
Maker::new(src).additive_expression().has_call_in_tail_position(&location)
}

#[test_case("a+b" => None; "location not in parse node")]
#[test_case("call()" => None; "fall-thru; location in node, but no function body")]
#[test_case("(function(){ return call(); })()" => ssome("return call ( ) ;"); "fall-thru; location in function body")]
#[test_case("(function(){ return call(); })() + 3" => ssome("return call ( ) ;"); "left-side add; location in function body")]
#[test_case("10 + (function(){ return call(); })()" => ssome("return call ( ) ;"); "right-side add; location in function body")]
#[test_case("(function(){ return call(); })() - 3" => ssome("return call ( ) ;"); "left-side subtract; location in function body")]
#[test_case("10 - (function(){ return call(); })()" => ssome("return call ( ) ;"); "right-side subtract; location in function body")]
fn body_containing_location(src: &str) -> Option<String> {
let location = find_call(src);
Maker::new(src)
.return_ok(true)
.additive_expression()
.body_containing_location(&location)
.map(|node| node.to_string())
}
}
13 changes: 13 additions & 0 deletions src/parser/arrow_function_definitions/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,19 @@ mod arrow_function {
fn location(src: &str) -> Location {
Maker::new(src).arrow_function().location()
}

#[test_case("x => 3" => None; "location not in parse node")]
#[test_case("x => { return call(); }" => ssome("return call ( ) ;"); "location in body")]
#[test_case("(x = call()) => { return x; }" => None; "location in params, but not in a body itself")]
#[test_case("(x = (function(z) { return call(); })()) => { return x; }" => ssome("return call ( ) ;"); "location in params")]
fn body_containing_location(src: &str) -> Option<String> {
let location = find_call(src);
Maker::new(src)
.return_ok(true)
.arrow_function()
.body_containing_location(&location)
.map(|node| node.to_string())
}
}

// ARROW PARAMETERS
Expand Down
6 changes: 0 additions & 6 deletions src/parser/continue_statement/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,6 @@ impl ContinueStatement {
label.early_errors(errs, strict);
}
}

#[expect(unused_variables)]
pub(crate) fn body_containing_location(&self, location: &Location) -> Option<ContainingBody> {
// Finds the FunctionBody, ConciseBody, or AsyncConciseBody that contains location most closely.
todo!()
}
}

#[cfg(test)]
Expand Down
12 changes: 12 additions & 0 deletions src/parser/declarations_and_variables/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1441,6 +1441,18 @@ mod array_binding_pattern {
fn contains(src: &str, kind: ParseNodeKind) -> bool {
Maker::new(src).array_binding_pattern().contains(kind)
}

#[test_case("[,,, /* call() */]" => None; "elisions only")]
#[test_case("[...a /* call() */]" => None; "binding rest element; no function body")]
#[test_case("[...[a=function(){return call();}]]" => ssome("return call ( ) ;"); "binding rest element; has function body")]
#[test_case("[a=function(){return call();},b]" => ssome("return call ( ) ;"); "binding element list; has function body on head")]
#[test_case("[a,b=function(){return call();}]" => ssome("return call ( ) ;"); "binding element list; has function body in tail")]
#[test_case("[a=function(){return call();},b,]" => ssome("return call ( ) ;"); "binding element list + empty rest; has function body on head")]
#[test_case("[a,...[b=function(){return call();}]]" => ssome("return call ( ) ;"); "binding element list + rest; has function body in rest")]
fn body_containing_location(src: &str) -> Option<String> {
let location = find_call(src);
Maker::new(src).array_binding_pattern().body_containing_location(&location).map(|node| node.to_string())
}
}

// BINDING REST PROPERTY
Expand Down
12 changes: 12 additions & 0 deletions src/parser/expression_statement/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,16 @@ mod expression_statement {
fn location(src: &str) -> Location {
Maker::new(src).expression_statement().location()
}

#[test_case("a;" => None; "location outside of source")]
#[test_case("(function () { return call(); })();" => Some("return call ( ) ;".to_string()); "call in function body")]
#[test_case("call();" => None; "call, but not in body")]
fn body_containing_location(src: &str) -> Option<String> {
let location = find_call(src);
Maker::new(src)
.return_ok(true)
.expression_statement()
.body_containing_location(&location)
.map(|node| node.to_string())
}
}
4 changes: 2 additions & 2 deletions src/parser/if_statement/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,11 +232,11 @@ impl IfStatement {
pub(crate) fn body_containing_location(&self, location: &Location) -> Option<ContainingBody> {
if self.location().contains(location) {
match self {
IfStatement::WithElse(expression, statement, statement1, location) => expression
IfStatement::WithElse(expression, statement, statement1, ..) => expression
.body_containing_location(location)
.or_else(|| statement.body_containing_location(location))
.or_else(|| statement1.body_containing_location(location)),
IfStatement::WithoutElse(expression, statement, location) => expression
IfStatement::WithoutElse(expression, statement, ..) => expression
.body_containing_location(location)
.or_else(|| statement.body_containing_location(location)),
}
Expand Down
Loading
Loading