Browse Source

Implement From<&str> for JsValue

refactor/interner
Haled Odat 1 year ago
parent
commit
c71731cc23
  1. 4
      boa_cli/src/debug/shape.rs
  2. 5
      boa_engine/src/builtins/array/array_iterator.rs
  3. 16
      boa_engine/src/builtins/array/tests.rs
  4. 7
      boa_engine/src/builtins/atomics/mod.rs
  5. 10
      boa_engine/src/builtins/bigint/tests.rs
  6. 8
      boa_engine/src/builtins/date/mod.rs
  7. 10
      boa_engine/src/builtins/date/tests.rs
  8. 66
      boa_engine/src/builtins/error/tests.rs
  9. 10
      boa_engine/src/builtins/function/tests.rs
  10. 26
      boa_engine/src/builtins/intl/collator/mod.rs
  11. 4
      boa_engine/src/builtins/intl/date_time_format.rs
  12. 14
      boa_engine/src/builtins/intl/list_format/mod.rs
  13. 2
      boa_engine/src/builtins/intl/locale/mod.rs
  14. 61
      boa_engine/src/builtins/intl/plural_rules/mod.rs
  15. 2
      boa_engine/src/builtins/intl/segmenter/iterator.rs
  16. 2
      boa_engine/src/builtins/intl/segmenter/mod.rs
  17. 6
      boa_engine/src/builtins/json/mod.rs
  18. 17
      boa_engine/src/builtins/json/tests.rs
  19. 3
      boa_engine/src/builtins/map/map_iterator.rs
  20. 18
      boa_engine/src/builtins/map/tests.rs
  21. 6
      boa_engine/src/builtins/mod.rs
  22. 8
      boa_engine/src/builtins/number/mod.rs
  23. 410
      boa_engine/src/builtins/number/tests.rs
  24. 4
      boa_engine/src/builtins/object/mod.rs
  25. 29
      boa_engine/src/builtins/object/tests.rs
  26. 17
      boa_engine/src/builtins/promise/mod.rs
  27. 9
      boa_engine/src/builtins/reflect/tests.rs
  28. 6
      boa_engine/src/builtins/regexp/mod.rs
  29. 3
      boa_engine/src/builtins/regexp/regexp_string_iterator.rs
  30. 16
      boa_engine/src/builtins/regexp/tests.rs
  31. 3
      boa_engine/src/builtins/set/set_iterator.rs
  32. 2
      boa_engine/src/builtins/string/mod.rs
  33. 2
      boa_engine/src/builtins/string/string_iterator.rs
  34. 115
      boa_engine/src/builtins/string/tests.rs
  35. 4
      boa_engine/src/builtins/symbol/tests.rs
  36. 4
      boa_engine/src/builtins/temporal/calendar/tests.rs
  37. 14
      boa_engine/src/builtins/temporal/duration/record.rs
  38. 2
      boa_engine/src/builtins/temporal/plain_date/mod.rs
  39. 8
      boa_engine/src/builtins/temporal/plain_year_month/mod.rs
  40. 8
      boa_engine/src/builtins/temporal/tests.rs
  41. 3
      boa_engine/src/builtins/weak/weak_ref.rs
  42. 2
      boa_engine/src/context/mod.rs
  43. 3
      boa_engine/src/module/mod.rs
  44. 2
      boa_engine/src/object/builtins/jsdate.rs
  45. 46
      boa_engine/src/object/builtins/jsmap.rs
  46. 2
      boa_engine/src/object/builtins/jspromise.rs
  47. 2
      boa_engine/src/object/mod.rs
  48. 20
      boa_engine/src/tests/control_flow/loops.rs
  49. 22
      boa_engine/src/tests/control_flow/mod.rs
  50. 6
      boa_engine/src/tests/env.rs
  51. 12
      boa_engine/src/tests/function.rs
  52. 6
      boa_engine/src/tests/mod.rs
  53. 34
      boa_engine/src/tests/operators.rs
  54. 8
      boa_engine/src/tests/spread.rs
  55. 8
      boa_engine/src/value/conversions/mod.rs
  56. 6
      boa_engine/src/value/conversions/serde_json.rs
  57. 26
      boa_engine/src/value/mod.rs
  58. 40
      boa_engine/src/value/tests.rs
  59. 26
      boa_engine/src/vm/tests.rs
  60. 2
      boa_examples/src/bin/classes.rs
  61. 10
      boa_examples/src/bin/closures.rs
  62. 4
      boa_examples/src/bin/futures.rs
  63. 6
      boa_examples/src/bin/host_defined.rs
  64. 10
      boa_examples/src/bin/jsarray.rs
  65. 14
      boa_examples/src/bin/jsdate.rs
  66. 31
      boa_examples/src/bin/jsmap.rs
  67. 6
      boa_examples/src/bin/jsregexp.rs
  68. 20
      boa_examples/src/bin/jsset.rs
  69. 3
      boa_examples/src/bin/jstypedarray.rs
  70. 23
      boa_examples/src/bin/modulehandler.rs
  71. 6
      boa_runtime/src/console/mod.rs
  72. 23
      boa_runtime/src/console/tests.rs
  73. 6
      boa_tester/src/exec/mod.rs

4
boa_cli/src/debug/shape.rs

@ -33,9 +33,9 @@ fn r#type(_: &JsValue, args: &[JsValue], _: &mut Context<'_>) -> JsResult<JsValu
let shape = object.shape(); let shape = object.shape();
Ok(if shape.is_shared() { Ok(if shape.is_shared() {
js_string!("shared") "shared"
} else { } else {
js_string!("unique") "unique"
} }
.into()) .into())
} }

5
boa_engine/src/builtins/array/array_iterator.rs

@ -11,7 +11,6 @@ use crate::{
}, },
context::intrinsics::Intrinsics, context::intrinsics::Intrinsics,
error::JsNativeError, error::JsNativeError,
js_string,
object::{JsObject, ObjectData}, object::{JsObject, ObjectData},
property::{Attribute, PropertyNameKind}, property::{Attribute, PropertyNameKind},
realm::Realm, realm::Realm,
@ -48,10 +47,10 @@ impl IntrinsicObject for ArrayIterator {
.iterator_prototypes() .iterator_prototypes()
.iterator(), .iterator(),
) )
.static_method(Self::next, js_string!("next"), 0) .static_method(Self::next, "next", 0)
.static_property( .static_property(
JsSymbol::to_string_tag(), JsSymbol::to_string_tag(),
js_string!("Array Iterator"), "Array Iterator",
Attribute::CONFIGURABLE, Attribute::CONFIGURABLE,
) )
.build(); .build();

16
boa_engine/src/builtins/array/tests.rs

@ -38,7 +38,7 @@ fn of() {
TestAction::assert("arrayEquals(Array.of(), [])"), TestAction::assert("arrayEquals(Array.of(), [])"),
TestAction::run("let a = Array.of.call(Date, 'a', undefined, 3);"), TestAction::run("let a = Array.of.call(Date, 'a', undefined, 3);"),
TestAction::assert("a instanceof Date"), TestAction::assert("a instanceof Date"),
TestAction::assert_eq("a[0]", js_string!("a")), TestAction::assert_eq("a[0]", "a"),
TestAction::assert_eq("a[1]", JsValue::undefined()), TestAction::assert_eq("a[1]", JsValue::undefined()),
TestAction::assert_eq("a[2]", 3), TestAction::assert_eq("a[2]", 3),
TestAction::assert_eq("a.length", 3), TestAction::assert_eq("a.length", 3),
@ -75,9 +75,9 @@ fn copy_within() {
fn join() { fn join() {
run_test_actions([ run_test_actions([
TestAction::assert_eq("[].join('.')", js_string!()), TestAction::assert_eq("[].join('.')", js_string!()),
TestAction::assert_eq("['a'].join('.')", js_string!("a")), TestAction::assert_eq("['a'].join('.')", "a"),
TestAction::assert_eq("['a', 'b', 'c'].join('.')", js_string!("a.b.c")), TestAction::assert_eq("['a', 'b', 'c'].join('.')", "a.b.c"),
TestAction::assert_eq("let a=[];a[0]=a;a[1]=a;a[2]=a;a.join()", js_string!(",,")), TestAction::assert_eq("let a=[];a[0]=a;a[1]=a;a[2]=a;a.join()", ",,"),
]); ]);
} }
@ -85,8 +85,8 @@ fn join() {
fn to_string() { fn to_string() {
run_test_actions([ run_test_actions([
TestAction::assert_eq("[].toString()", js_string!()), TestAction::assert_eq("[].toString()", js_string!()),
TestAction::assert_eq("['a'].toString()", js_string!("a")), TestAction::assert_eq("['a'].toString()", "a"),
TestAction::assert_eq("['a', 'b', 'c'].toString()", js_string!("a,b,c")), TestAction::assert_eq("['a', 'b', 'c'].toString()", "a,b,c"),
]); ]);
} }
@ -116,7 +116,7 @@ fn every() {
fn find() { fn find() {
run_test_actions([TestAction::assert_eq( run_test_actions([TestAction::assert_eq(
"['a', 'b', 'c'].find(e => e == 'a')", "['a', 'b', 'c'].find(e => e == 'a')",
js_string!("a"), "a",
)]); )]);
} }
@ -350,7 +350,7 @@ fn fill_obj_ref() {
let a = new Array(3).fill(obj); let a = new Array(3).fill(obj);
obj.hi = 'hi' obj.hi = 'hi'
"#}), "#}),
TestAction::assert_eq("a[2].hi", js_string!("hi")), TestAction::assert_eq("a[2].hi", "hi"),
]); ]);
} }

7
boa_engine/src/builtins/atomics/mod.rs

@ -17,7 +17,6 @@ use std::sync::atomic::Ordering;
use crate::{ use crate::{
builtins::BuiltInObject, builtins::BuiltInObject,
context::intrinsics::Intrinsics, context::intrinsics::Intrinsics,
js_string,
object::{JsObject, Object}, object::{JsObject, Object},
property::Attribute, property::Attribute,
realm::Realm, realm::Realm,
@ -472,9 +471,9 @@ impl Atomics {
}; };
Ok(match result { Ok(match result {
futex::AtomicsWaitResult::NotEqual => js_string!("not-equal"), futex::AtomicsWaitResult::NotEqual => "not-equal",
futex::AtomicsWaitResult::TimedOut => js_string!("timed-out"), futex::AtomicsWaitResult::TimedOut => "timed-out",
futex::AtomicsWaitResult::Ok => js_string!("ok"), futex::AtomicsWaitResult::Ok => "ok",
} }
.into()) .into())
} }

10
boa_engine/src/builtins/bigint/tests.rs

@ -1,4 +1,4 @@
use crate::{js_string, run_test_actions, JsBigInt, JsNativeErrorKind, TestAction}; use crate::{run_test_actions, JsBigInt, JsNativeErrorKind, TestAction};
#[test] #[test]
fn equality() { fn equality() {
@ -147,10 +147,10 @@ fn operations() {
#[test] #[test]
fn to_string() { fn to_string() {
run_test_actions([ run_test_actions([
TestAction::assert_eq("1000n.toString()", js_string!("1000")), TestAction::assert_eq("1000n.toString()", "1000"),
TestAction::assert_eq("1000n.toString(2)", js_string!("1111101000")), TestAction::assert_eq("1000n.toString(2)", "1111101000"),
TestAction::assert_eq("255n.toString(16)", js_string!("ff")), TestAction::assert_eq("255n.toString(16)", "ff"),
TestAction::assert_eq("1000n.toString(36)", js_string!("rs")), TestAction::assert_eq("1000n.toString(36)", "rs"),
]); ]);
} }

8
boa_engine/src/builtins/date/mod.rs

@ -1246,7 +1246,7 @@ impl Date {
// 2. Let tv be ? thisTimeValue(O). // 2. Let tv be ? thisTimeValue(O).
let Some(tv) = this_time_value(this)?.and_then(NaiveDateTime::from_timestamp_millis) else { let Some(tv) = this_time_value(this)?.and_then(NaiveDateTime::from_timestamp_millis) else {
// 3. If tv is NaN, return "Invalid Date". // 3. If tv is NaN, return "Invalid Date".
return Ok(js_string!("Invalid Date").into()); return Ok("Invalid Date".into());
}; };
// 4. Let t be LocalTime(tv). // 4. Let t be LocalTime(tv).
@ -1393,7 +1393,7 @@ impl Date {
// 1. Let tv be ? thisTimeValue(this value). // 1. Let tv be ? thisTimeValue(this value).
// 2. Return ToDateString(tv). // 2. Return ToDateString(tv).
let Some(tv) = this_time_value(this)?.and_then(NaiveDateTime::from_timestamp_millis) else { let Some(tv) = this_time_value(this)?.and_then(NaiveDateTime::from_timestamp_millis) else {
return Ok(js_string!("Invalid Date").into()); return Ok("Invalid Date".into());
}; };
Ok(js_string!(context Ok(js_string!(context
.host_hooks() .host_hooks()
@ -1422,7 +1422,7 @@ impl Date {
// 2. Let tv be ? thisTimeValue(O). // 2. Let tv be ? thisTimeValue(O).
let Some(tv) = this_time_value(this)?.and_then(NaiveDateTime::from_timestamp_millis) else { let Some(tv) = this_time_value(this)?.and_then(NaiveDateTime::from_timestamp_millis) else {
// 3. If tv is NaN, return "Invalid Date". // 3. If tv is NaN, return "Invalid Date".
return Ok(js_string!("Invalid Date").into()); return Ok("Invalid Date".into());
}; };
// 4. Let t be LocalTime(tv). // 4. Let t be LocalTime(tv).
@ -1452,7 +1452,7 @@ impl Date {
// 1. Let O be this Date object. // 1. Let O be this Date object.
let Some(t) = this_time_value(this)?.and_then(NaiveDateTime::from_timestamp_millis) else { let Some(t) = this_time_value(this)?.and_then(NaiveDateTime::from_timestamp_millis) else {
// 3. If tv is NaN, return "Invalid Date". // 3. If tv is NaN, return "Invalid Date".
return Ok(js_string!("Invalid Date").into()); return Ok("Invalid Date".into());
}; };
// 2. Let tv be ? thisTimeValue(O). // 2. Let tv be ? thisTimeValue(O).

10
boa_engine/src/builtins/date/tests.rs

@ -762,7 +762,7 @@ fn date_proto_set_utc_seconds() {
fn date_proto_to_date_string() { fn date_proto_to_date_string() {
run_test_actions([TestAction::assert_eq( run_test_actions([TestAction::assert_eq(
"new Date(2020, 6, 8, 9, 16, 15, 779).toDateString()", "new Date(2020, 6, 8, 9, 16, 15, 779).toDateString()",
js_string!("Wed Jul 08 2020"), "Wed Jul 08 2020",
)]); )]);
} }
@ -770,7 +770,7 @@ fn date_proto_to_date_string() {
fn date_proto_to_gmt_string() { fn date_proto_to_gmt_string() {
run_test_actions([TestAction::assert_eq( run_test_actions([TestAction::assert_eq(
"new Date(Date.UTC(2020, 6, 8, 9, 16, 15, 779)).toGMTString()", "new Date(Date.UTC(2020, 6, 8, 9, 16, 15, 779)).toGMTString()",
js_string!("Wed, 08 Jul 2020 09:16:15 GMT"), "Wed, 08 Jul 2020 09:16:15 GMT",
)]); )]);
} }
@ -778,7 +778,7 @@ fn date_proto_to_gmt_string() {
fn date_proto_to_iso_string() { fn date_proto_to_iso_string() {
run_test_actions([TestAction::assert_eq( run_test_actions([TestAction::assert_eq(
"new Date(Date.UTC(2020, 6, 8, 9, 16, 15, 779)).toISOString()", "new Date(Date.UTC(2020, 6, 8, 9, 16, 15, 779)).toISOString()",
js_string!("2020-07-08T09:16:15.779Z"), "2020-07-08T09:16:15.779Z",
)]); )]);
} }
@ -786,7 +786,7 @@ fn date_proto_to_iso_string() {
fn date_proto_to_json() { fn date_proto_to_json() {
run_test_actions([TestAction::assert_eq( run_test_actions([TestAction::assert_eq(
"new Date(Date.UTC(2020, 6, 8, 9, 16, 15, 779)).toJSON()", "new Date(Date.UTC(2020, 6, 8, 9, 16, 15, 779)).toJSON()",
js_string!("2020-07-08T09:16:15.779Z"), "2020-07-08T09:16:15.779Z",
)]); )]);
} }
@ -826,7 +826,7 @@ fn date_proto_to_time_string() {
fn date_proto_to_utc_string() { fn date_proto_to_utc_string() {
run_test_actions([TestAction::assert_eq( run_test_actions([TestAction::assert_eq(
"new Date(Date.UTC(2020, 6, 8, 9, 16, 15, 779)).toUTCString()", "new Date(Date.UTC(2020, 6, 8, 9, 16, 15, 779)).toUTCString()",
js_string!("Wed, 08 Jul 2020 09:16:15 GMT"), "Wed, 08 Jul 2020 09:16:15 GMT",
)]); )]);
} }

66
boa_engine/src/builtins/error/tests.rs

@ -1,42 +1,24 @@
use crate::{js_string, run_test_actions, TestAction}; use crate::{run_test_actions, TestAction};
use indoc::indoc; use indoc::indoc;
#[test] #[test]
fn error_to_string() { fn error_to_string() {
run_test_actions([ run_test_actions([
TestAction::assert_eq("(new Error('1')).toString()", js_string!("Error: 1")), TestAction::assert_eq("(new Error('1')).toString()", "Error: 1"),
TestAction::assert_eq( TestAction::assert_eq("(new RangeError('2')).toString()", "RangeError: 2"),
"(new RangeError('2')).toString()", TestAction::assert_eq("(new ReferenceError('3')).toString()", "ReferenceError: 3"),
js_string!("RangeError: 2"), TestAction::assert_eq("(new SyntaxError('4')).toString()", "SyntaxError: 4"),
), TestAction::assert_eq("(new TypeError('5')).toString()", "TypeError: 5"),
TestAction::assert_eq( TestAction::assert_eq("(new EvalError('6')).toString()", "EvalError: 6"),
"(new ReferenceError('3')).toString()", TestAction::assert_eq("(new URIError('7')).toString()", "URIError: 7"),
js_string!("ReferenceError: 3"),
),
TestAction::assert_eq(
"(new SyntaxError('4')).toString()",
js_string!("SyntaxError: 4"),
),
TestAction::assert_eq(
"(new TypeError('5')).toString()",
js_string!("TypeError: 5"),
),
TestAction::assert_eq(
"(new EvalError('6')).toString()",
js_string!("EvalError: 6"),
),
TestAction::assert_eq("(new URIError('7')).toString()", js_string!("URIError: 7")),
// no message // no message
TestAction::assert_eq("(new Error()).toString()", js_string!("Error")), TestAction::assert_eq("(new Error()).toString()", "Error"),
TestAction::assert_eq("(new RangeError()).toString()", js_string!("RangeError")), TestAction::assert_eq("(new RangeError()).toString()", "RangeError"),
TestAction::assert_eq( TestAction::assert_eq("(new ReferenceError()).toString()", "ReferenceError"),
"(new ReferenceError()).toString()", TestAction::assert_eq("(new SyntaxError()).toString()", "SyntaxError"),
js_string!("ReferenceError"), TestAction::assert_eq("(new TypeError()).toString()", "TypeError"),
), TestAction::assert_eq("(new EvalError()).toString()", "EvalError"),
TestAction::assert_eq("(new SyntaxError()).toString()", js_string!("SyntaxError")), TestAction::assert_eq("(new URIError()).toString()", "URIError"),
TestAction::assert_eq("(new TypeError()).toString()", js_string!("TypeError")),
TestAction::assert_eq("(new EvalError()).toString()", js_string!("EvalError")),
TestAction::assert_eq("(new URIError()).toString()", js_string!("URIError")),
// no name // no name
TestAction::assert_eq( TestAction::assert_eq(
indoc! {r#" indoc! {r#"
@ -44,7 +26,7 @@ fn error_to_string() {
message.name = ''; message.name = '';
message.toString() message.toString()
"#}, "#},
js_string!("message"), "message",
), ),
]); ]);
} }
@ -52,14 +34,14 @@ fn error_to_string() {
#[test] #[test]
fn error_names() { fn error_names() {
run_test_actions([ run_test_actions([
TestAction::assert_eq("Error.name", js_string!("Error")), TestAction::assert_eq("Error.name", "Error"),
TestAction::assert_eq("EvalError.name", js_string!("EvalError")), TestAction::assert_eq("EvalError.name", "EvalError"),
TestAction::assert_eq("RangeError.name", js_string!("RangeError")), TestAction::assert_eq("RangeError.name", "RangeError"),
TestAction::assert_eq("ReferenceError.name", js_string!("ReferenceError")), TestAction::assert_eq("ReferenceError.name", "ReferenceError"),
TestAction::assert_eq("SyntaxError.name", js_string!("SyntaxError")), TestAction::assert_eq("SyntaxError.name", "SyntaxError"),
TestAction::assert_eq("URIError.name", js_string!("URIError")), TestAction::assert_eq("URIError.name", "URIError"),
TestAction::assert_eq("TypeError.name", js_string!("TypeError")), TestAction::assert_eq("TypeError.name", "TypeError"),
TestAction::assert_eq("AggregateError.name", js_string!("AggregateError")), TestAction::assert_eq("AggregateError.name", "AggregateError"),
]); ]);
} }

10
boa_engine/src/builtins/function/tests.rs

@ -69,7 +69,7 @@ fn function_prototype() {
fn function_prototype_call() { fn function_prototype_call() {
run_test_actions([TestAction::assert_eq( run_test_actions([TestAction::assert_eq(
"Object.prototype.toString.call(new Error())", "Object.prototype.toString.call(new Error())",
js_string!("[object Error]"), "[object Error]",
)]); )]);
} }
@ -134,9 +134,9 @@ fn closure_capture_clone() {
let object = JsObject::with_object_proto(ctx.intrinsics()); let object = JsObject::with_object_proto(ctx.intrinsics());
object object
.define_property_or_throw( .define_property_or_throw(
js_string!("key"), "key",
PropertyDescriptor::builder() PropertyDescriptor::builder()
.value(js_string!(" world!")) .value(" world!")
.writable(false) .writable(false)
.enumerable(false) .enumerable(false)
.configurable(false), .configurable(false),
@ -168,10 +168,10 @@ fn closure_capture_clone() {
.name("closure") .name("closure")
.build(); .build();
ctx.register_global_property(js_string!("closure"), func, Attribute::default()) ctx.register_global_property("closure", func, Attribute::default())
.unwrap(); .unwrap();
}), }),
TestAction::assert_eq("closure()", js_string!("Hello world!")), TestAction::assert_eq("closure()", "Hello world!"),
]); ]);
} }

26
boa_engine/src/builtins/intl/collator/mod.rs

@ -160,7 +160,7 @@ impl IntrinsicObject for Collator {
.static_method(Self::supported_locales_of, "supportedLocalesOf", 1) .static_method(Self::supported_locales_of, "supportedLocalesOf", 1)
.property( .property(
JsSymbol::to_string_tag(), JsSymbol::to_string_tag(),
js_string!("Intl.Collator"), "Intl.Collator",
Attribute::CONFIGURABLE, Attribute::CONFIGURABLE,
) )
.accessor("compare", Some(compare), None, Attribute::CONFIGURABLE) .accessor("compare", Some(compare), None, Attribute::CONFIGURABLE)
@ -520,8 +520,8 @@ impl Collator {
.create_data_property_or_throw( .create_data_property_or_throw(
"usage", "usage",
match collator.usage { match collator.usage {
Usage::Search => js_string!("search"), Usage::Search => "search",
Usage::Sort => js_string!("sort"), Usage::Sort => "sort",
}, },
context, context,
) )
@ -530,24 +530,24 @@ impl Collator {
.create_data_property_or_throw( .create_data_property_or_throw(
"sensitivity", "sensitivity",
match collator.sensitivity { match collator.sensitivity {
Sensitivity::Base => js_string!("base"), Sensitivity::Base => "base",
Sensitivity::Accent => js_string!("accent"), Sensitivity::Accent => "accent",
Sensitivity::Case => js_string!("case"), Sensitivity::Case => "case",
Sensitivity::Variant => js_string!("variant"), Sensitivity::Variant => "variant",
}, },
context, context,
) )
.expect("operation must not fail per the spec"); .expect("operation must not fail per the spec");
options options
.create_data_property_or_throw( .create_data_property_or_throw(
js_string!("ignorePunctuation"), "ignorePunctuation",
collator.ignore_punctuation, collator.ignore_punctuation,
context, context,
) )
.expect("operation must not fail per the spec"); .expect("operation must not fail per the spec");
options options
.create_data_property_or_throw( .create_data_property_or_throw(
js_string!("collation"), "collation",
js_string!(collator.collation.to_string()), js_string!(collator.collation.to_string()),
context, context,
) )
@ -558,11 +558,11 @@ impl Collator {
if let Some(kf) = collator.case_first { if let Some(kf) = collator.case_first {
options options
.create_data_property_or_throw( .create_data_property_or_throw(
js_string!("caseFirst"), "caseFirst",
match kf { match kf {
CaseFirst::Off => js_string!("false"), CaseFirst::Off => "false",
CaseFirst::LowerFirst => js_string!("lower"), CaseFirst::LowerFirst => "lower",
CaseFirst::UpperFirst => js_string!("upper"), CaseFirst::UpperFirst => "upper",
_ => unreachable!(), _ => unreachable!(),
}, },
context, context,

4
boa_engine/src/builtins/intl/date_time_format.rs

@ -267,7 +267,7 @@ pub(crate) fn to_date_time_options(
// a. For each property name prop of « "year", "month", "day" », do // a. For each property name prop of « "year", "month", "day" », do
for property in ["year", "month", "day"] { for property in ["year", "month", "day"] {
// i. Perform ? CreateDataPropertyOrThrow(options, prop, "numeric"). // i. Perform ? CreateDataPropertyOrThrow(options, prop, "numeric").
options.create_data_property_or_throw(property, js_string!("numeric"), context)?; options.create_data_property_or_throw(property, "numeric", context)?;
} }
} }
@ -276,7 +276,7 @@ pub(crate) fn to_date_time_options(
// a. For each property name prop of « "hour", "minute", "second" », do // a. For each property name prop of « "hour", "minute", "second" », do
for property in ["hour", "minute", "second"] { for property in ["hour", "minute", "second"] {
// i. Perform ? CreateDataPropertyOrThrow(options, prop, "numeric"). // i. Perform ? CreateDataPropertyOrThrow(options, prop, "numeric").
options.create_data_property_or_throw(property, js_string!("numeric"), context)?; options.create_data_property_or_throw(property, "numeric", context)?;
} }
} }

14
boa_engine/src/builtins/intl/list_format/mod.rs

@ -51,7 +51,7 @@ impl IntrinsicObject for ListFormat {
.static_method(Self::supported_locales_of, "supportedLocalesOf", 1) .static_method(Self::supported_locales_of, "supportedLocalesOf", 1)
.property( .property(
JsSymbol::to_string_tag(), JsSymbol::to_string_tag(),
js_string!("Intl.ListFormat"), "Intl.ListFormat",
Attribute::CONFIGURABLE, Attribute::CONFIGURABLE,
) )
.method(Self::format, "format", 1) .method(Self::format, "format", 1)
@ -437,9 +437,9 @@ impl ListFormat {
.create_data_property_or_throw( .create_data_property_or_throw(
"type", "type",
match lf.typ { match lf.typ {
ListFormatType::Conjunction => js_string!("conjunction"), ListFormatType::Conjunction => "conjunction",
ListFormatType::Disjunction => js_string!("disjunction"), ListFormatType::Disjunction => "disjunction",
ListFormatType::Unit => js_string!("unit"), ListFormatType::Unit => "unit",
}, },
context, context,
) )
@ -448,9 +448,9 @@ impl ListFormat {
.create_data_property_or_throw( .create_data_property_or_throw(
"style", "style",
match lf.style { match lf.style {
ListLength::Wide => js_string!("long"), ListLength::Wide => "long",
ListLength::Short => js_string!("short"), ListLength::Short => "short",
ListLength::Narrow => js_string!("narrow"), ListLength::Narrow => "narrow",
_ => unreachable!(), _ => unreachable!(),
}, },
context, context,

2
boa_engine/src/builtins/intl/locale/mod.rs

@ -76,7 +76,7 @@ impl IntrinsicObject for Locale {
BuiltInBuilder::from_standard_constructor::<Self>(realm) BuiltInBuilder::from_standard_constructor::<Self>(realm)
.property( .property(
JsSymbol::to_string_tag(), JsSymbol::to_string_tag(),
js_string!("Intl.Locale"), "Intl.Locale",
Attribute::CONFIGURABLE, Attribute::CONFIGURABLE,
) )
.method(Self::maximize, "maximize", 0) .method(Self::maximize, "maximize", 0)

61
boa_engine/src/builtins/intl/plural_rules/mod.rs

@ -54,7 +54,7 @@ impl IntrinsicObject for PluralRules {
.static_method(Self::supported_locales_of, "supportedLocalesOf", 1) .static_method(Self::supported_locales_of, "supportedLocalesOf", 1)
.property( .property(
JsSymbol::to_string_tag(), JsSymbol::to_string_tag(),
js_string!("Intl.PluralRules"), "Intl.PluralRules",
Attribute::CONFIGURABLE, Attribute::CONFIGURABLE,
) )
.method(Self::resolved_options, "resolvedOptions", 0) .method(Self::resolved_options, "resolvedOptions", 0)
@ -266,14 +266,14 @@ impl PluralRules {
.property( .property(
"type", "type",
match plural_rules.rule_type { match plural_rules.rule_type {
PluralRuleType::Cardinal => js_string!("cardinal"), PluralRuleType::Cardinal => "cardinal",
PluralRuleType::Ordinal => js_string!("ordinal"), PluralRuleType::Ordinal => "ordinal",
_ => js_string!("unknown"), _ => "unknown",
}, },
Attribute::all(), Attribute::all(),
) )
.property( .property(
js_string!("minimumIntegerDigits"), "minimumIntegerDigits",
plural_rules.format_options.minimum_integer_digits, plural_rules.format_options.minimum_integer_digits,
Attribute::all(), Attribute::all(),
); );
@ -282,16 +282,8 @@ impl PluralRules {
plural_rules.format_options.rounding_type.fraction_digits() plural_rules.format_options.rounding_type.fraction_digits()
{ {
options options
.property( .property("minimumFractionDigits", minimum, Attribute::all())
js_string!("minimumFractionDigits"), .property("maximumFractionDigits", maximum, Attribute::all());
minimum,
Attribute::all(),
)
.property(
js_string!("maximumFractionDigits"),
maximum,
Attribute::all(),
);
} }
if let Some(Extrema { minimum, maximum }) = plural_rules if let Some(Extrema { minimum, maximum }) = plural_rules
@ -300,31 +292,23 @@ impl PluralRules {
.significant_digits() .significant_digits()
{ {
options options
.property( .property("minimumSignificantDigits", minimum, Attribute::all())
js_string!("minimumSignificantDigits"), .property("maximumSignificantDigits", maximum, Attribute::all());
minimum,
Attribute::all(),
)
.property(
js_string!("maximumSignificantDigits"),
maximum,
Attribute::all(),
);
} }
options options
.property( .property(
js_string!("roundingMode"), "roundingMode",
js_string!(plural_rules.format_options.rounding_mode.to_string()), js_string!(plural_rules.format_options.rounding_mode.to_string()),
Attribute::all(), Attribute::all(),
) )
.property( .property(
js_string!("roundingIncrement"), "roundingIncrement",
plural_rules.format_options.rounding_increment, plural_rules.format_options.rounding_increment,
Attribute::all(), Attribute::all(),
) )
.property( .property(
js_string!("trailingZeroDisplay"), "trailingZeroDisplay",
js_string!(plural_rules js_string!(plural_rules
.format_options .format_options
.trailing_zero_display .trailing_zero_display
@ -343,11 +327,7 @@ impl PluralRules {
); );
// 6. Perform ! CreateDataProperty(options, "pluralCategories", CreateArrayFromList(pluralCategories)). // 6. Perform ! CreateDataProperty(options, "pluralCategories", CreateArrayFromList(pluralCategories)).
options.property( options.property("pluralCategories", plural_categories, Attribute::all());
js_string!("pluralCategories"),
plural_categories,
Attribute::all(),
);
// 7. If pr.[[RoundingType]] is morePrecision, then // 7. If pr.[[RoundingType]] is morePrecision, then
// a. Perform ! CreateDataPropertyOrThrow(options, "roundingPriority", "morePrecision"). // a. Perform ! CreateDataPropertyOrThrow(options, "roundingPriority", "morePrecision").
@ -356,7 +336,7 @@ impl PluralRules {
// 9. Else, // 9. Else,
// a. Perform ! CreateDataPropertyOrThrow(options, "roundingPriority", "auto"). // a. Perform ! CreateDataPropertyOrThrow(options, "roundingPriority", "auto").
options.property( options.property(
js_string!("roundingPriority"), "roundingPriority",
js_string!(plural_rules.format_options.rounding_priority.to_string()), js_string!(plural_rules.format_options.rounding_priority.to_string()),
Attribute::all(), Attribute::all(),
); );
@ -410,11 +390,12 @@ fn resolve_plural(plural_rules: &PluralRules, n: f64) -> ResolvedPlural {
fn plural_category_to_js_string(category: PluralCategory) -> JsString { fn plural_category_to_js_string(category: PluralCategory) -> JsString {
match category { match category {
PluralCategory::Zero => js_string!("zero"), PluralCategory::Zero => "zero",
PluralCategory::One => js_string!("one"), PluralCategory::One => "one",
PluralCategory::Two => js_string!("two"), PluralCategory::Two => "two",
PluralCategory::Few => js_string!("few"), PluralCategory::Few => "few",
PluralCategory::Many => js_string!("many"), PluralCategory::Many => "many",
PluralCategory::Other => js_string!("other"), PluralCategory::Other => "other",
} }
.into()
} }

2
boa_engine/src/builtins/intl/segmenter/iterator.rs

@ -68,7 +68,7 @@ impl IntrinsicObject for SegmentIterator {
BuiltInBuilder::with_intrinsic::<Self>(realm) BuiltInBuilder::with_intrinsic::<Self>(realm)
.static_property( .static_property(
JsSymbol::to_string_tag(), JsSymbol::to_string_tag(),
js_string!("Segmenter String Iterator"), "Segmenter String Iterator",
Attribute::CONFIGURABLE, Attribute::CONFIGURABLE,
) )
.static_method(Self::next, "next", 0) .static_method(Self::next, "next", 0)

2
boa_engine/src/builtins/intl/segmenter/mod.rs

@ -90,7 +90,7 @@ impl IntrinsicObject for Segmenter {
.static_method(Self::supported_locales_of, "supportedLocalesOf", 1) .static_method(Self::supported_locales_of, "supportedLocalesOf", 1)
.property( .property(
JsSymbol::to_string_tag(), JsSymbol::to_string_tag(),
js_string!("Intl.Segmenter"), "Intl.Segmenter",
Attribute::CONFIGURABLE, Attribute::CONFIGURABLE,
) )
.method(Self::resolved_options, "resolvedOptions", 0) .method(Self::resolved_options, "resolvedOptions", 0)

6
boa_engine/src/builtins/json/mod.rs

@ -358,7 +358,7 @@ impl Json {
.to_integer_or_infinity(context) .to_integer_or_infinity(context)
.expect("ToIntegerOrInfinity cannot fail on number") .expect("ToIntegerOrInfinity cannot fail on number")
{ {
IntegerOrInfinity::PositiveInfinity => js_string!(" "), IntegerOrInfinity::PositiveInfinity => " ".into(),
IntegerOrInfinity::NegativeInfinity => js_string!(), IntegerOrInfinity::NegativeInfinity => js_string!(),
IntegerOrInfinity::Integer(i) if i < 1 => js_string!(), IntegerOrInfinity::Integer(i) if i < 1 => js_string!(),
IntegerOrInfinity::Integer(i) => { IntegerOrInfinity::Integer(i) => {
@ -466,7 +466,7 @@ impl Json {
// 5. If value is null, return "null". // 5. If value is null, return "null".
if value.is_null() { if value.is_null() {
return Ok(Some(js_string!("null"))); return Ok(Some("null".into()));
} }
// 6. If value is true, return "true". // 6. If value is true, return "true".
@ -496,7 +496,7 @@ impl Json {
} }
// b. Return "null". // b. Return "null".
return Ok(Some(js_string!("null"))); return Ok(Some("null".into()));
} }
// 10. If Type(value) is BigInt, throw a TypeError exception. // 10. If Type(value) is BigInt, throw a TypeError exception.

17
boa_engine/src/builtins/json/tests.rs

@ -5,7 +5,7 @@ use crate::{js_string, run_test_actions, JsNativeErrorKind, JsValue, TestAction}
#[test] #[test]
fn json_sanity() { fn json_sanity() {
run_test_actions([ run_test_actions([
TestAction::assert_eq(r#"JSON.parse('{"aaa":"bbb"}').aaa"#, js_string!("bbb")), TestAction::assert_eq(r#"JSON.parse('{"aaa":"bbb"}').aaa"#, "bbb"),
TestAction::assert_eq( TestAction::assert_eq(
r#"JSON.stringify({aaa: 'bbb'})"#, r#"JSON.stringify({aaa: 'bbb'})"#,
js_string!(r#"{"aaa":"bbb"}"#), js_string!(r#"{"aaa":"bbb"}"#),
@ -89,7 +89,7 @@ fn json_stringify_object_array() {
fn json_stringify_array_converts_undefined_to_null() { fn json_stringify_array_converts_undefined_to_null() {
run_test_actions([TestAction::assert_eq( run_test_actions([TestAction::assert_eq(
"JSON.stringify([undefined])", "JSON.stringify([undefined])",
js_string!("[null]"), "[null]",
)]); )]);
} }
@ -97,7 +97,7 @@ fn json_stringify_array_converts_undefined_to_null() {
fn json_stringify_array_converts_function_to_null() { fn json_stringify_array_converts_function_to_null() {
run_test_actions([TestAction::assert_eq( run_test_actions([TestAction::assert_eq(
"JSON.stringify([() => {}])", "JSON.stringify([() => {}])",
js_string!("[null]"), "[null]",
)]); )]);
} }
@ -105,7 +105,7 @@ fn json_stringify_array_converts_function_to_null() {
fn json_stringify_array_converts_symbol_to_null() { fn json_stringify_array_converts_symbol_to_null() {
run_test_actions([TestAction::assert_eq( run_test_actions([TestAction::assert_eq(
"JSON.stringify([Symbol()])", "JSON.stringify([Symbol()])",
js_string!("[null]"), "[null]",
)]); )]);
} }
#[test] #[test]
@ -150,10 +150,7 @@ fn json_stringify_no_args() {
#[test] #[test]
fn json_stringify_fractional_numbers() { fn json_stringify_fractional_numbers() {
run_test_actions([TestAction::assert_eq( run_test_actions([TestAction::assert_eq("JSON.stringify(1.2)", "1.2")]);
"JSON.stringify(1.2)",
js_string!("1.2"),
)]);
} }
#[test] #[test]
@ -278,8 +275,8 @@ fn json_parse_object_with_reviver() {
var jsonObj = JSON.parse(jsonString, dataReviver); var jsonObj = JSON.parse(jsonString, dataReviver);
"#}), "#}),
TestAction::assert_eq("jsonObj.firstname", js_string!("boa")), TestAction::assert_eq("jsonObj.firstname", "boa"),
TestAction::assert_eq("jsonObj.lastname", js_string!("interpreter")), TestAction::assert_eq("jsonObj.lastname", "interpreter"),
]); ]);
} }

3
boa_engine/src/builtins/map/map_iterator.rs

@ -12,7 +12,6 @@ use crate::{
}, },
context::intrinsics::Intrinsics, context::intrinsics::Intrinsics,
error::JsNativeError, error::JsNativeError,
js_string,
object::{JsObject, ObjectData}, object::{JsObject, ObjectData},
property::{Attribute, PropertyNameKind}, property::{Attribute, PropertyNameKind},
realm::Realm, realm::Realm,
@ -52,7 +51,7 @@ impl IntrinsicObject for MapIterator {
.static_method(Self::next, "next", 0) .static_method(Self::next, "next", 0)
.static_property( .static_property(
JsSymbol::to_string_tag(), JsSymbol::to_string_tag(),
js_string!("Map Iterator"), "Map Iterator",
Attribute::CONFIGURABLE, Attribute::CONFIGURABLE,
) )
.build(); .build();

18
boa_engine/src/builtins/map/tests.rs

@ -1,4 +1,4 @@
use crate::{js_string, run_test_actions, JsNativeErrorKind, JsValue, TestAction}; use crate::{run_test_actions, JsNativeErrorKind, JsValue, TestAction};
use indoc::indoc; use indoc::indoc;
#[test] #[test]
@ -74,7 +74,7 @@ fn merge() {
let merged2 = new Map([...second, ...third]); let merged2 = new Map([...second, ...third]);
"#}), "#}),
TestAction::assert_eq("merged1.size", 3), TestAction::assert_eq("merged1.size", 3),
TestAction::assert_eq("merged1.get('2')", js_string!("second two")), TestAction::assert_eq("merged1.get('2')", "second two"),
TestAction::assert_eq("merged2.size", 4), TestAction::assert_eq("merged2.size", 4),
]); ]);
} }
@ -85,8 +85,8 @@ fn get() {
TestAction::run(indoc! {r#" TestAction::run(indoc! {r#"
let map = new Map([["1", "one"], ["2", "two"]]); let map = new Map([["1", "one"], ["2", "two"]]);
"#}), "#}),
TestAction::assert_eq("map.get('1')", js_string!("one")), TestAction::assert_eq("map.get('1')", "one"),
TestAction::assert_eq("map.get('2')", js_string!("two")), TestAction::assert_eq("map.get('2')", "two"),
TestAction::assert_eq("map.get('3')", JsValue::undefined()), TestAction::assert_eq("map.get('3')", JsValue::undefined()),
TestAction::assert_eq("map.get()", JsValue::undefined()), TestAction::assert_eq("map.get()", JsValue::undefined()),
]); ]);
@ -98,7 +98,7 @@ fn set() {
TestAction::run("let map = new Map();"), TestAction::run("let map = new Map();"),
TestAction::assert("map.set(); map.has(undefined)"), TestAction::assert("map.set(); map.has(undefined)"),
TestAction::assert_eq("map.get()", JsValue::undefined()), TestAction::assert_eq("map.get()", JsValue::undefined()),
TestAction::assert_eq("map.set('1', 'one'); map.get('1')", js_string!("one")), TestAction::assert_eq("map.set('1', 'one'); map.get('1')", "one"),
TestAction::assert("map.set('2'); map.has('2')"), TestAction::assert("map.set('2'); map.has('2')"),
TestAction::assert_eq("map.get('2')", JsValue::undefined()), TestAction::assert_eq("map.get('2')", JsValue::undefined()),
]); ]);
@ -148,7 +148,7 @@ fn keys() {
let item2 = keysIterator.next(); let item2 = keysIterator.next();
let item3 = keysIterator.next(); let item3 = keysIterator.next();
"#}), "#}),
TestAction::assert_eq("item1.value", js_string!("0")), TestAction::assert_eq("item1.value", "0"),
TestAction::assert_eq("item2.value", 1), TestAction::assert_eq("item2.value", 1),
TestAction::assert("item3.done"), TestAction::assert("item3.done"),
]); ]);
@ -187,8 +187,8 @@ fn values() {
let item2 = valuesIterator.next(); let item2 = valuesIterator.next();
let item3 = valuesIterator.next(); let item3 = valuesIterator.next();
"#}), "#}),
TestAction::assert_eq("item1.value", js_string!("foo")), TestAction::assert_eq("item1.value", "foo"),
TestAction::assert_eq("item2.value", js_string!("bar")), TestAction::assert_eq("item2.value", "bar"),
TestAction::assert("item3.done"), TestAction::assert("item3.done"),
]); ]);
} }
@ -201,7 +201,7 @@ fn modify_key() {
let map = new Map([[obj, "one"]]); let map = new Map([[obj, "one"]]);
obj.field = "Value"; obj.field = "Value";
"#}), "#}),
TestAction::assert_eq("map.get(obj)", js_string!("one")), TestAction::assert_eq("map.get(obj)", "one"),
]); ]);
} }

6
boa_engine/src/builtins/mod.rs

@ -870,7 +870,7 @@ impl<'ctx> BuiltInBuilder<'ctx, OrdinaryObject> {
realm, realm,
function, function,
length: 0, length: 0,
name: js_string!(""), name: js_string!(),
} }
} }
@ -883,7 +883,7 @@ impl<'ctx> BuiltInBuilder<'ctx, OrdinaryObject> {
object: I::get(realm.intrinsics()), object: I::get(realm.intrinsics()),
kind: Callable { kind: Callable {
function, function,
name: js_string!(""), name: js_string!(),
length: 0, length: 0,
kind: OrdinaryFunction, kind: OrdinaryFunction,
realm: realm.clone(), realm: realm.clone(),
@ -902,7 +902,7 @@ impl<'ctx> BuiltInBuilder<'ctx, OrdinaryObject> {
object, object,
kind: Callable { kind: Callable {
function, function,
name: js_string!(""), name: js_string!(),
length: 0, length: 0,
kind: OrdinaryFunction, kind: OrdinaryFunction,
realm: realm.clone(), realm: realm.clone(),

8
boa_engine/src/builtins/number/mod.rs

@ -677,13 +677,13 @@ impl Number {
} }
if x == -0. { if x == -0. {
return Ok(JsValue::new(js_string!("0"))); return Ok(JsValue::new("0"));
} else if x.is_nan() { } else if x.is_nan() {
return Ok(JsValue::new(js_string!("NaN"))); return Ok(JsValue::new("NaN"));
} else if x.is_infinite() && x.is_sign_positive() { } else if x.is_infinite() && x.is_sign_positive() {
return Ok(JsValue::new(js_string!("Infinity"))); return Ok(JsValue::new("Infinity"));
} else if x.is_infinite() && x.is_sign_negative() { } else if x.is_infinite() && x.is_sign_negative() {
return Ok(JsValue::new(js_string!("-Infinity"))); return Ok(JsValue::new("-Infinity"));
} }
// This is a Optimization from the v8 source code to print values that can fit in a single character // This is a Optimization from the v8 source code to print values that can fit in a single character

410
boa_engine/src/builtins/number/tests.rs

@ -1,11 +1,10 @@
use crate::{ use crate::{
builtins::Number, js_string, run_test_actions, value::AbstractRelation, JsNativeErrorKind, builtins::Number, run_test_actions, value::AbstractRelation, JsNativeErrorKind, TestAction,
TestAction,
}; };
#[test] #[test]
fn integer_number_primitive_to_number_object() { fn integer_number_primitive_to_number_object() {
run_test_actions([TestAction::assert_eq("(100).toString()", js_string!("100"))]); run_test_actions([TestAction::assert_eq("(100).toString()", "100")]);
} }
#[test] #[test]
@ -25,136 +24,115 @@ fn call_number() {
#[test] #[test]
fn to_exponential() { fn to_exponential() {
run_test_actions([ run_test_actions([
TestAction::assert_eq("Number().toExponential()", js_string!("0e+0")), TestAction::assert_eq("Number().toExponential()", "0e+0"),
TestAction::assert_eq("Number(5).toExponential()", js_string!("5e+0")), TestAction::assert_eq("Number(5).toExponential()", "5e+0"),
TestAction::assert_eq("Number(1.234).toExponential()", js_string!("1.234e+0")), TestAction::assert_eq("Number(1.234).toExponential()", "1.234e+0"),
TestAction::assert_eq("Number(1234).toExponential()", js_string!("1.234e+3")), TestAction::assert_eq("Number(1234).toExponential()", "1.234e+3"),
TestAction::assert_eq( TestAction::assert_eq("Number('I am also not a number').toExponential()", "NaN"),
"Number('I am also not a number').toExponential()", TestAction::assert_eq("Number('1.23e+2').toExponential()", "1.23e+2"),
js_string!("NaN"),
),
TestAction::assert_eq("Number('1.23e+2').toExponential()", js_string!("1.23e+2")),
]); ]);
} }
#[test] #[test]
fn to_fixed() { fn to_fixed() {
run_test_actions([ run_test_actions([
TestAction::assert_eq("Number().toFixed()", js_string!("0")), TestAction::assert_eq("Number().toFixed()", "0"),
TestAction::assert_eq("Number('3.456e+4').toFixed()", js_string!("34560")), TestAction::assert_eq("Number('3.456e+4').toFixed()", "34560"),
TestAction::assert_eq("Number('3.456e-4').toFixed()", js_string!("0")), TestAction::assert_eq("Number('3.456e-4').toFixed()", "0"),
TestAction::assert_eq("Number(5).toFixed()", js_string!("5")), TestAction::assert_eq("Number(5).toFixed()", "5"),
TestAction::assert_eq( TestAction::assert_eq("Number('I am also not a number').toFixed()", "NaN"),
"Number('I am also not a number').toFixed()", TestAction::assert_eq("(1.35).toFixed(1)", "1.4"),
js_string!("NaN"),
),
TestAction::assert_eq("(1.35).toFixed(1)", js_string!("1.4")),
// Test cases from https://source.chromium.org/chromium/chromium/src/+/main:v8/test/mjsunit/number-tostring-func.js;l=157-240;drc=aa3518a0f37245ebe8f062dce97ee492e2a41652 // Test cases from https://source.chromium.org/chromium/chromium/src/+/main:v8/test/mjsunit/number-tostring-func.js;l=157-240;drc=aa3518a0f37245ebe8f062dce97ee492e2a41652
TestAction::assert_eq("(NaN).toFixed(2)", js_string!("NaN")), TestAction::assert_eq("(NaN).toFixed(2)", "NaN"),
TestAction::assert_eq("(1/0).toFixed(2)", js_string!("Infinity")), TestAction::assert_eq("(1/0).toFixed(2)", "Infinity"),
TestAction::assert_eq("(-1/0).toFixed(2)", js_string!("-Infinity")), TestAction::assert_eq("(-1/0).toFixed(2)", "-Infinity"),
TestAction::assert_eq( TestAction::assert_eq(
"(1111111111111111111111).toFixed(8)", "(1111111111111111111111).toFixed(8)",
js_string!("1.1111111111111111e+21"), "1.1111111111111111e+21",
), ),
TestAction::assert_eq("(0.1).toFixed(1)", js_string!("0.1")), TestAction::assert_eq("(0.1).toFixed(1)", "0.1"),
TestAction::assert_eq("(0.1).toFixed(2)", js_string!("0.10")), TestAction::assert_eq("(0.1).toFixed(2)", "0.10"),
TestAction::assert_eq("(0.1).toFixed(3)", js_string!("0.100")), TestAction::assert_eq("(0.1).toFixed(3)", "0.100"),
TestAction::assert_eq("(0.01).toFixed(2)", js_string!("0.01")), TestAction::assert_eq("(0.01).toFixed(2)", "0.01"),
TestAction::assert_eq("(0.01).toFixed(3)", js_string!("0.010")), TestAction::assert_eq("(0.01).toFixed(3)", "0.010"),
TestAction::assert_eq("(0.01).toFixed(4)", js_string!("0.0100")), TestAction::assert_eq("(0.01).toFixed(4)", "0.0100"),
TestAction::assert_eq("(0.001).toFixed(2)", js_string!("0.00")), TestAction::assert_eq("(0.001).toFixed(2)", "0.00"),
TestAction::assert_eq("(0.001).toFixed(3)", js_string!("0.001")), TestAction::assert_eq("(0.001).toFixed(3)", "0.001"),
TestAction::assert_eq("(0.001).toFixed(4)", js_string!("0.0010")), TestAction::assert_eq("(0.001).toFixed(4)", "0.0010"),
TestAction::assert_eq("(1).toFixed(4)", js_string!("1.0000")), TestAction::assert_eq("(1).toFixed(4)", "1.0000"),
TestAction::assert_eq("(1).toFixed(1)", js_string!("1.0")), TestAction::assert_eq("(1).toFixed(1)", "1.0"),
TestAction::assert_eq("(1).toFixed(0)", js_string!("1")), TestAction::assert_eq("(1).toFixed(0)", "1"),
TestAction::assert_eq("(12).toFixed(0)", js_string!("12")), TestAction::assert_eq("(12).toFixed(0)", "12"),
TestAction::assert_eq("(1.1).toFixed(0)", js_string!("1")), TestAction::assert_eq("(1.1).toFixed(0)", "1"),
TestAction::assert_eq("(12.1).toFixed(0)", js_string!("12")), TestAction::assert_eq("(12.1).toFixed(0)", "12"),
TestAction::assert_eq("(1.12).toFixed(0)", js_string!("1")), TestAction::assert_eq("(1.12).toFixed(0)", "1"),
TestAction::assert_eq("(12.12).toFixed(0)", js_string!("12")), TestAction::assert_eq("(12.12).toFixed(0)", "12"),
TestAction::assert_eq("(0.0000006).toFixed(7)", js_string!("0.0000006")), TestAction::assert_eq("(0.0000006).toFixed(7)", "0.0000006"),
TestAction::assert_eq("(0.00000006).toFixed(8)", js_string!("0.00000006")), TestAction::assert_eq("(0.00000006).toFixed(8)", "0.00000006"),
TestAction::assert_eq("(0.00000006).toFixed(9)", js_string!("0.000000060")), TestAction::assert_eq("(0.00000006).toFixed(9)", "0.000000060"),
TestAction::assert_eq("(0.00000006).toFixed(10)", js_string!("0.0000000600")), TestAction::assert_eq("(0.00000006).toFixed(10)", "0.0000000600"),
TestAction::assert_eq("(0).toFixed(0)", js_string!("0")), TestAction::assert_eq("(0).toFixed(0)", "0"),
TestAction::assert_eq("(0).toFixed(1)", js_string!("0.0")), TestAction::assert_eq("(0).toFixed(1)", "0.0"),
TestAction::assert_eq("(0).toFixed(2)", js_string!("0.00")), TestAction::assert_eq("(0).toFixed(2)", "0.00"),
TestAction::assert_eq( TestAction::assert_eq(
"(-1111111111111111111111).toFixed(8)", "(-1111111111111111111111).toFixed(8)",
js_string!("-1.1111111111111111e+21"), "-1.1111111111111111e+21",
), ),
TestAction::assert_eq("(-0.1).toFixed(1)", js_string!("-0.1")), TestAction::assert_eq("(-0.1).toFixed(1)", "-0.1"),
TestAction::assert_eq("(-0.1).toFixed(2)", js_string!("-0.10")), TestAction::assert_eq("(-0.1).toFixed(2)", "-0.10"),
TestAction::assert_eq("(-0.1).toFixed(3)", js_string!("-0.100")), TestAction::assert_eq("(-0.1).toFixed(3)", "-0.100"),
TestAction::assert_eq("(-0.01).toFixed(2)", js_string!("-0.01")), TestAction::assert_eq("(-0.01).toFixed(2)", "-0.01"),
TestAction::assert_eq("(-0.01).toFixed(3)", js_string!("-0.010")), TestAction::assert_eq("(-0.01).toFixed(3)", "-0.010"),
TestAction::assert_eq("(-0.01).toFixed(4)", js_string!("-0.0100")), TestAction::assert_eq("(-0.01).toFixed(4)", "-0.0100"),
TestAction::assert_eq("(-0.001).toFixed(2)", js_string!("-0.00")), TestAction::assert_eq("(-0.001).toFixed(2)", "-0.00"),
TestAction::assert_eq("(-0.001).toFixed(3)", js_string!("-0.001")), TestAction::assert_eq("(-0.001).toFixed(3)", "-0.001"),
TestAction::assert_eq("(-0.001).toFixed(4)", js_string!("-0.0010")), TestAction::assert_eq("(-0.001).toFixed(4)", "-0.0010"),
TestAction::assert_eq("(-1).toFixed(4)", js_string!("-1.0000")), TestAction::assert_eq("(-1).toFixed(4)", "-1.0000"),
TestAction::assert_eq("(-1).toFixed(1)", js_string!("-1.0")), TestAction::assert_eq("(-1).toFixed(1)", "-1.0"),
TestAction::assert_eq("(-1).toFixed(0)", js_string!("-1")), TestAction::assert_eq("(-1).toFixed(0)", "-1"),
TestAction::assert_eq("(-1.1).toFixed(0)", js_string!("-1")), TestAction::assert_eq("(-1.1).toFixed(0)", "-1"),
TestAction::assert_eq("(-12.1).toFixed(0)", js_string!("-12")), TestAction::assert_eq("(-12.1).toFixed(0)", "-12"),
TestAction::assert_eq("(-1.12).toFixed(0)", js_string!("-1")), TestAction::assert_eq("(-1.12).toFixed(0)", "-1"),
TestAction::assert_eq("(-12.12).toFixed(0)", js_string!("-12")), TestAction::assert_eq("(-12.12).toFixed(0)", "-12"),
TestAction::assert_eq("(-0.0000006).toFixed(7)", js_string!("-0.0000006")), TestAction::assert_eq("(-0.0000006).toFixed(7)", "-0.0000006"),
TestAction::assert_eq("(-0.00000006).toFixed(8)", js_string!("-0.00000006")), TestAction::assert_eq("(-0.00000006).toFixed(8)", "-0.00000006"),
TestAction::assert_eq("(-0.00000006).toFixed(9)", js_string!("-0.000000060")), TestAction::assert_eq("(-0.00000006).toFixed(9)", "-0.000000060"),
TestAction::assert_eq("(-0.00000006).toFixed(10)", js_string!("-0.0000000600")), TestAction::assert_eq("(-0.00000006).toFixed(10)", "-0.0000000600"),
TestAction::assert_eq("(-0).toFixed(0)", js_string!("0")), TestAction::assert_eq("(-0).toFixed(0)", "0"),
TestAction::assert_eq("(-0).toFixed(1)", js_string!("0.0")), TestAction::assert_eq("(-0).toFixed(1)", "0.0"),
TestAction::assert_eq("(-0).toFixed(2)", js_string!("0.00")), TestAction::assert_eq("(-0).toFixed(2)", "0.00"),
TestAction::assert_eq("(0.00001).toFixed(5)", js_string!("0.00001")), TestAction::assert_eq("(0.00001).toFixed(5)", "0.00001"),
TestAction::assert_eq( TestAction::assert_eq(
"(0.0000000000000000001).toFixed(20)", "(0.0000000000000000001).toFixed(20)",
js_string!("0.00000000000000000010"), "0.00000000000000000010",
),
TestAction::assert_eq("(0.00001).toFixed(17)", js_string!("0.00001000000000000")),
TestAction::assert_eq("(1).toFixed(17)", js_string!("1.00000000000000000")),
TestAction::assert_eq(
"(100000000000000128).toFixed(1)",
js_string!("100000000000000128.0"),
),
TestAction::assert_eq(
"(10000000000000128).toFixed(2)",
js_string!("10000000000000128.00"),
), ),
TestAction::assert_eq("(0.00001).toFixed(17)", "0.00001000000000000"),
TestAction::assert_eq("(1).toFixed(17)", "1.00000000000000000"),
TestAction::assert_eq("(100000000000000128).toFixed(1)", "100000000000000128.0"),
TestAction::assert_eq("(10000000000000128).toFixed(2)", "10000000000000128.00"),
TestAction::assert_eq( TestAction::assert_eq(
"(10000000000000128).toFixed(20)", "(10000000000000128).toFixed(20)",
js_string!("10000000000000128.00000000000000000000"), "10000000000000128.00000000000000000000",
), ),
TestAction::assert_eq("(-42).toFixed(3)", js_string!("-42.000")), TestAction::assert_eq("(-42).toFixed(3)", "-42.000"),
TestAction::assert_eq( TestAction::assert_eq(
"(-0.0000000000000000001).toFixed(20)", "(-0.0000000000000000001).toFixed(20)",
js_string!("-0.00000000000000000010"), "-0.00000000000000000010",
), ),
TestAction::assert_eq( TestAction::assert_eq("(0.123123123123123).toFixed(20)", "0.12312312312312299889"),
"(0.123123123123123).toFixed(20)", TestAction::assert_eq("(-1000000000000000128).toFixed()", "-1000000000000000128"),
js_string!("0.12312312312312299889"), TestAction::assert_eq("(0).toFixed()", "0"),
), TestAction::assert_eq("(1000000000000000128).toFixed()", "1000000000000000128"),
TestAction::assert_eq( TestAction::assert_eq("(1000).toFixed()", "1000"),
"(-1000000000000000128).toFixed()", TestAction::assert_eq("(0.00001).toFixed()", "0"),
js_string!("-1000000000000000128"),
),
TestAction::assert_eq("(0).toFixed()", js_string!("0")),
TestAction::assert_eq(
"(1000000000000000128).toFixed()",
js_string!("1000000000000000128"),
),
TestAction::assert_eq("(1000).toFixed()", js_string!("1000")),
TestAction::assert_eq("(0.00001).toFixed()", js_string!("0")),
// Test that we round up even when the last digit generated is even. // Test that we round up even when the last digit generated is even.
// dtoa does not do this in its original form. // dtoa does not do this in its original form.
TestAction::assert_eq("(0.5).toFixed(0)", js_string!("1")), TestAction::assert_eq("(0.5).toFixed(0)", "1"),
TestAction::assert_eq("(-0.5).toFixed(0)", js_string!("-1")), TestAction::assert_eq("(-0.5).toFixed(0)", "-1"),
TestAction::assert_eq("(1.25).toFixed(1)", js_string!("1.3")), TestAction::assert_eq("(1.25).toFixed(1)", "1.3"),
// This is bizare, but Spidermonkey and KJS behave the same. // This is bizare, but Spidermonkey and KJS behave the same.
TestAction::assert_eq("(234.2040).toFixed(4)", js_string!("234.2040")), TestAction::assert_eq("(234.2040).toFixed(4)", "234.2040"),
TestAction::assert_eq("(234.2040506).toFixed(4)", js_string!("234.2041")), TestAction::assert_eq("(234.2040506).toFixed(4)", "234.2041"),
]); ]);
} }
@ -162,8 +140,8 @@ fn to_fixed() {
#[test] #[test]
fn issue_2609() { fn issue_2609() {
run_test_actions([ run_test_actions([
TestAction::assert_eq("(1.25).toFixed(1)", js_string!("1.3")), TestAction::assert_eq("(1.25).toFixed(1)", "1.3"),
TestAction::assert_eq("(1.35).toFixed(1)", js_string!("1.4")), TestAction::assert_eq("(1.35).toFixed(1)", "1.4"),
]); ]);
} }
@ -172,10 +150,10 @@ fn to_locale_string() {
// TODO: We don't actually do any locale checking here // TODO: We don't actually do any locale checking here
// To honor the spec we should print numbers according to user locale. // To honor the spec we should print numbers according to user locale.
run_test_actions([ run_test_actions([
TestAction::assert_eq("Number().toLocaleString()", js_string!("0")), TestAction::assert_eq("Number().toLocaleString()", "0"),
TestAction::assert_eq("Number(5).toLocaleString()", js_string!("5")), TestAction::assert_eq("Number(5).toLocaleString()", "5"),
TestAction::assert_eq("Number('345600').toLocaleString()", js_string!("345600")), TestAction::assert_eq("Number('345600').toLocaleString()", "345600"),
TestAction::assert_eq("Number(-25).toLocaleString()", js_string!("-25")), TestAction::assert_eq("Number(-25).toLocaleString()", "-25"),
]); ]);
} }
@ -183,21 +161,21 @@ fn to_locale_string() {
fn to_precision() { fn to_precision() {
const ERROR: &str = "precision must be an integer at least 1 and no greater than 100"; const ERROR: &str = "precision must be an integer at least 1 and no greater than 100";
run_test_actions([ run_test_actions([
TestAction::assert_eq("(1/0).toPrecision(3)", js_string!("Infinity")), TestAction::assert_eq("(1/0).toPrecision(3)", "Infinity"),
TestAction::assert_eq("Number().toPrecision()", js_string!("0")), TestAction::assert_eq("Number().toPrecision()", "0"),
TestAction::assert_eq("Number().toPrecision(undefined)", js_string!("0")), TestAction::assert_eq("Number().toPrecision(undefined)", "0"),
TestAction::assert_eq("(123456789).toPrecision(1)", js_string!("1e+8")), TestAction::assert_eq("(123456789).toPrecision(1)", "1e+8"),
TestAction::assert_eq("(123456789).toPrecision(4)", js_string!("1.235e+8")), TestAction::assert_eq("(123456789).toPrecision(4)", "1.235e+8"),
TestAction::assert_eq("(123456789).toPrecision(9)", js_string!("123456789")), TestAction::assert_eq("(123456789).toPrecision(9)", "123456789"),
TestAction::assert_eq("(-123456789).toPrecision(4)", js_string!("-1.235e+8")), TestAction::assert_eq("(-123456789).toPrecision(4)", "-1.235e+8"),
TestAction::assert_eq( TestAction::assert_eq(
"(123456789).toPrecision(50)", "(123456789).toPrecision(50)",
js_string!("123456789.00000000000000000000000000000000000000000"), "123456789.00000000000000000000000000000000000000000",
), ),
TestAction::assert_eq("(0.1).toPrecision(4)", js_string!("0.1000")), TestAction::assert_eq("(0.1).toPrecision(4)", "0.1000"),
TestAction::assert_eq( TestAction::assert_eq(
"(1/3).toPrecision(60)", "(1/3).toPrecision(60)",
js_string!("0.333333333333333314829616256247390992939472198486328125000000"), "0.333333333333333314829616256247390992939472198486328125000000",
), ),
TestAction::assert_native_error("(1).toPrecision(101)", JsNativeErrorKind::Range, ERROR), TestAction::assert_native_error("(1).toPrecision(101)", JsNativeErrorKind::Range, ERROR),
TestAction::assert_native_error("(1).toPrecision(0)", JsNativeErrorKind::Range, ERROR), TestAction::assert_native_error("(1).toPrecision(0)", JsNativeErrorKind::Range, ERROR),
@ -209,132 +187,90 @@ fn to_precision() {
#[test] #[test]
fn to_string() { fn to_string() {
run_test_actions([ run_test_actions([
TestAction::assert_eq("Number(NaN).toString()", js_string!("NaN")), TestAction::assert_eq("Number(NaN).toString()", "NaN"),
TestAction::assert_eq("Number(1/0).toString()", js_string!("Infinity")), TestAction::assert_eq("Number(1/0).toString()", "Infinity"),
TestAction::assert_eq("Number(-1/0).toString()", js_string!("-Infinity")), TestAction::assert_eq("Number(-1/0).toString()", "-Infinity"),
TestAction::assert_eq("Number(0).toString()", js_string!("0")), TestAction::assert_eq("Number(0).toString()", "0"),
TestAction::assert_eq("Number(9).toString()", js_string!("9")), TestAction::assert_eq("Number(9).toString()", "9"),
TestAction::assert_eq("Number(90).toString()", js_string!("90")), TestAction::assert_eq("Number(90).toString()", "90"),
TestAction::assert_eq("Number(90.12).toString()", js_string!("90.12")), TestAction::assert_eq("Number(90.12).toString()", "90.12"),
TestAction::assert_eq("Number(0.1).toString()", js_string!("0.1")), TestAction::assert_eq("Number(0.1).toString()", "0.1"),
TestAction::assert_eq("Number(0.01).toString()", js_string!("0.01")), TestAction::assert_eq("Number(0.01).toString()", "0.01"),
TestAction::assert_eq("Number(0.0123).toString()", js_string!("0.0123")), TestAction::assert_eq("Number(0.0123).toString()", "0.0123"),
TestAction::assert_eq("Number(0.00001).toString()", js_string!("0.00001")), TestAction::assert_eq("Number(0.00001).toString()", "0.00001"),
TestAction::assert_eq("Number(0.000001).toString()", js_string!("0.000001")), TestAction::assert_eq("Number(0.000001).toString()", "0.000001"),
TestAction::assert_eq("Number(NaN).toString(16)", js_string!("NaN")), TestAction::assert_eq("Number(NaN).toString(16)", "NaN"),
TestAction::assert_eq("Number(1/0).toString(16)", js_string!("Infinity")), TestAction::assert_eq("Number(1/0).toString(16)", "Infinity"),
TestAction::assert_eq("Number(-1/0).toString(16)", js_string!("-Infinity")), TestAction::assert_eq("Number(-1/0).toString(16)", "-Infinity"),
TestAction::assert_eq("Number(0).toString(16)", js_string!("0")), TestAction::assert_eq("Number(0).toString(16)", "0"),
TestAction::assert_eq("Number(9).toString(16)", js_string!("9")), TestAction::assert_eq("Number(9).toString(16)", "9"),
TestAction::assert_eq("Number(90).toString(16)", js_string!("5a")), TestAction::assert_eq("Number(90).toString(16)", "5a"),
TestAction::assert_eq("Number(90.12).toString(16)", js_string!("5a.1eb851eb852")), TestAction::assert_eq("Number(90.12).toString(16)", "5a.1eb851eb852"),
TestAction::assert_eq("Number(0.1).toString(16)", js_string!("0.1999999999999a")), TestAction::assert_eq("Number(0.1).toString(16)", "0.1999999999999a"),
TestAction::assert_eq("Number(0.01).toString(16)", js_string!("0.028f5c28f5c28f6")), TestAction::assert_eq("Number(0.01).toString(16)", "0.028f5c28f5c28f6"),
TestAction::assert_eq( TestAction::assert_eq("Number(0.0123).toString(16)", "0.032617c1bda511a"),
"Number(0.0123).toString(16)",
js_string!("0.032617c1bda511a"),
),
TestAction::assert_eq( TestAction::assert_eq(
"Number(111111111111111111111).toString(16)", "Number(111111111111111111111).toString(16)",
js_string!("605f9f6dd18bc8000"), "605f9f6dd18bc8000",
), ),
TestAction::assert_eq( TestAction::assert_eq(
"Number(1111111111111111111111).toString(16)", "Number(1111111111111111111111).toString(16)",
js_string!("3c3bc3a4a2f75c0000"), "3c3bc3a4a2f75c0000",
), ),
TestAction::assert_eq( TestAction::assert_eq(
"Number(11111111111111111111111).toString(16)", "Number(11111111111111111111111).toString(16)",
js_string!("25a55a46e5da9a00000"), "25a55a46e5da9a00000",
),
TestAction::assert_eq(
"Number(0.00001).toString(16)",
js_string!("0.0000a7c5ac471b4788"),
),
TestAction::assert_eq(
"Number(0.000001).toString(16)",
js_string!("0.000010c6f7a0b5ed8d"),
),
TestAction::assert_eq(
"Number(0.0000001).toString(16)",
js_string!("0.000001ad7f29abcaf48"),
),
TestAction::assert_eq(
"Number(0.00000012).toString(16)",
js_string!("0.000002036565348d256"),
),
TestAction::assert_eq(
"Number(0.000000123).toString(16)",
js_string!("0.0000021047ee22aa466"),
),
TestAction::assert_eq(
"Number(0.00000001).toString(16)",
js_string!("0.0000002af31dc4611874"),
),
TestAction::assert_eq(
"Number(0.000000012).toString(16)",
js_string!("0.000000338a23b87483be"),
), ),
TestAction::assert_eq("Number(0.00001).toString(16)", "0.0000a7c5ac471b4788"),
TestAction::assert_eq("Number(0.000001).toString(16)", "0.000010c6f7a0b5ed8d"),
TestAction::assert_eq("Number(0.0000001).toString(16)", "0.000001ad7f29abcaf48"),
TestAction::assert_eq("Number(0.00000012).toString(16)", "0.000002036565348d256"),
TestAction::assert_eq("Number(0.000000123).toString(16)", "0.0000021047ee22aa466"),
TestAction::assert_eq("Number(0.00000001).toString(16)", "0.0000002af31dc4611874"),
TestAction::assert_eq("Number(0.000000012).toString(16)", "0.000000338a23b87483be"),
TestAction::assert_eq( TestAction::assert_eq(
"Number(0.0000000123).toString(16)", "Number(0.0000000123).toString(16)",
js_string!("0.00000034d3fe36aaa0a2"), "0.00000034d3fe36aaa0a2",
), ),
TestAction::assert_eq("Number(-0).toString(16)", js_string!("0")), TestAction::assert_eq("Number(-0).toString(16)", "0"),
TestAction::assert_eq("Number(-9).toString(16)", js_string!("-9")), TestAction::assert_eq("Number(-9).toString(16)", "-9"),
// //
TestAction::assert_eq("Number(-90).toString(16)", js_string!("-5a")), TestAction::assert_eq("Number(-90).toString(16)", "-5a"),
TestAction::assert_eq("Number(-90.12).toString(16)", js_string!("-5a.1eb851eb852")), TestAction::assert_eq("Number(-90.12).toString(16)", "-5a.1eb851eb852"),
TestAction::assert_eq("Number(-0.1).toString(16)", js_string!("-0.1999999999999a")), TestAction::assert_eq("Number(-0.1).toString(16)", "-0.1999999999999a"),
TestAction::assert_eq( TestAction::assert_eq("Number(-0.01).toString(16)", "-0.028f5c28f5c28f6"),
"Number(-0.01).toString(16)", TestAction::assert_eq("Number(-0.0123).toString(16)", "-0.032617c1bda511a"),
js_string!("-0.028f5c28f5c28f6"),
),
TestAction::assert_eq(
"Number(-0.0123).toString(16)",
js_string!("-0.032617c1bda511a"),
),
TestAction::assert_eq( TestAction::assert_eq(
"Number(-111111111111111111111).toString(16)", "Number(-111111111111111111111).toString(16)",
js_string!("-605f9f6dd18bc8000"), "-605f9f6dd18bc8000",
), ),
TestAction::assert_eq( TestAction::assert_eq(
"Number(-1111111111111111111111).toString(16)", "Number(-1111111111111111111111).toString(16)",
js_string!("-3c3bc3a4a2f75c0000"), "-3c3bc3a4a2f75c0000",
), ),
TestAction::assert_eq( TestAction::assert_eq(
"Number(-11111111111111111111111).toString(16)", "Number(-11111111111111111111111).toString(16)",
js_string!("-25a55a46e5da9a00000"), "-25a55a46e5da9a00000",
),
TestAction::assert_eq(
"Number(-0.00001).toString(16)",
js_string!("-0.0000a7c5ac471b4788"),
),
TestAction::assert_eq(
"Number(-0.000001).toString(16)",
js_string!("-0.000010c6f7a0b5ed8d"),
),
TestAction::assert_eq(
"Number(-0.0000001).toString(16)",
js_string!("-0.000001ad7f29abcaf48"),
),
TestAction::assert_eq(
"Number(-0.00000012).toString(16)",
js_string!("-0.000002036565348d256"),
), ),
TestAction::assert_eq("Number(-0.00001).toString(16)", "-0.0000a7c5ac471b4788"),
TestAction::assert_eq("Number(-0.000001).toString(16)", "-0.000010c6f7a0b5ed8d"),
TestAction::assert_eq("Number(-0.0000001).toString(16)", "-0.000001ad7f29abcaf48"),
TestAction::assert_eq("Number(-0.00000012).toString(16)", "-0.000002036565348d256"),
TestAction::assert_eq( TestAction::assert_eq(
"Number(-0.000000123).toString(16)", "Number(-0.000000123).toString(16)",
js_string!("-0.0000021047ee22aa466"), "-0.0000021047ee22aa466",
), ),
TestAction::assert_eq( TestAction::assert_eq(
"Number(-0.00000001).toString(16)", "Number(-0.00000001).toString(16)",
js_string!("-0.0000002af31dc4611874"), "-0.0000002af31dc4611874",
), ),
TestAction::assert_eq( TestAction::assert_eq(
"Number(-0.000000012).toString(16)", "Number(-0.000000012).toString(16)",
js_string!("-0.000000338a23b87483be"), "-0.000000338a23b87483be",
), ),
TestAction::assert_eq( TestAction::assert_eq(
"Number(-0.0000000123).toString(16)", "Number(-0.0000000123).toString(16)",
js_string!("-0.00000034d3fe36aaa0a2"), "-0.00000034d3fe36aaa0a2",
), ),
]); ]);
} }
@ -342,26 +278,26 @@ fn to_string() {
#[test] #[test]
fn num_to_string_exponential() { fn num_to_string_exponential() {
run_test_actions([ run_test_actions([
TestAction::assert_eq("(0).toString()", js_string!("0")), TestAction::assert_eq("(0).toString()", "0"),
TestAction::assert_eq("(-0).toString()", js_string!("0")), TestAction::assert_eq("(-0).toString()", "0"),
TestAction::assert_eq( TestAction::assert_eq(
"(111111111111111111111).toString()", "(111111111111111111111).toString()",
js_string!("111111111111111110000"), "111111111111111110000",
), ),
TestAction::assert_eq( TestAction::assert_eq(
"(1111111111111111111111).toString()", "(1111111111111111111111).toString()",
js_string!("1.1111111111111111e+21"), "1.1111111111111111e+21",
), ),
TestAction::assert_eq( TestAction::assert_eq(
"(11111111111111111111111).toString()", "(11111111111111111111111).toString()",
js_string!("1.1111111111111111e+22"), "1.1111111111111111e+22",
), ),
TestAction::assert_eq("(0.0000001).toString()", js_string!("1e-7")), TestAction::assert_eq("(0.0000001).toString()", "1e-7"),
TestAction::assert_eq("(0.00000012).toString()", js_string!("1.2e-7")), TestAction::assert_eq("(0.00000012).toString()", "1.2e-7"),
TestAction::assert_eq("(0.000000123).toString()", js_string!("1.23e-7")), TestAction::assert_eq("(0.000000123).toString()", "1.23e-7"),
TestAction::assert_eq("(0.00000001).toString()", js_string!("1e-8")), TestAction::assert_eq("(0.00000001).toString()", "1e-8"),
TestAction::assert_eq("(0.000000012).toString()", js_string!("1.2e-8")), TestAction::assert_eq("(0.000000012).toString()", "1.2e-8"),
TestAction::assert_eq("(0.0000000123).toString()", js_string!("1.23e-8")), TestAction::assert_eq("(0.0000000123).toString()", "1.23e-8"),
]); ]);
} }
@ -640,13 +576,7 @@ fn number_is_safe_integer() {
#[test] #[test]
fn issue_2717() { fn issue_2717() {
run_test_actions([ run_test_actions([
TestAction::assert_eq( TestAction::assert_eq("(0.1600057092765239).toString(36)", "0.5rd85dm1ixq"),
"(0.1600057092765239).toString(36)", TestAction::assert_eq("(0.23046743672210102).toString(36)", "0.8aoosla2phj"),
js_string!("0.5rd85dm1ixq"),
),
TestAction::assert_eq(
"(0.23046743672210102).toString(36)",
js_string!("0.8aoosla2phj"),
),
]); ]);
} }

4
boa_engine/src/builtins/object/mod.rs

@ -793,11 +793,11 @@ impl Object {
) -> JsResult<JsValue> { ) -> JsResult<JsValue> {
// 1. If the this value is undefined, return "[object Undefined]". // 1. If the this value is undefined, return "[object Undefined]".
if this.is_undefined() { if this.is_undefined() {
return Ok(js_string!("[object Undefined]").into()); return Ok("[object Undefined]".into());
} }
// 2. If the this value is null, return "[object Null]". // 2. If the this value is null, return "[object Null]".
if this.is_null() { if this.is_null() {
return Ok(js_string!("[object Null]").into()); return Ok("[object Null]".into());
} }
// 3. Let O be ! ToObject(this value). // 3. Let O be ! ToObject(this value).
let o = this.to_object(context).expect("toObject cannot fail here"); let o = this.to_object(context).expect("toObject cannot fail here");

29
boa_engine/src/builtins/object/tests.rs

@ -1,4 +1,4 @@
use crate::{js_string, run_test_actions, JsNativeErrorKind, JsValue, TestAction}; use crate::{run_test_actions, JsNativeErrorKind, JsValue, TestAction};
use indoc::indoc; use indoc::indoc;
#[test] #[test]
@ -137,21 +137,18 @@ fn object_to_string() {
"#}), "#}),
TestAction::assert_eq( TestAction::assert_eq(
"Object.prototype.toString.call(undefined)", "Object.prototype.toString.call(undefined)",
js_string!("[object Undefined]"), "[object Undefined]",
), ),
TestAction::assert_eq( TestAction::assert_eq("Object.prototype.toString.call(null)", "[object Null]"),
"Object.prototype.toString.call(null)", TestAction::assert_eq("[].toString()", "[object Array]"),
js_string!("[object Null]"), TestAction::assert_eq("(() => {}).toString()", "[object Function]"),
), TestAction::assert_eq("(new Error('')).toString()", "[object Error]"),
TestAction::assert_eq("[].toString()", js_string!("[object Array]")), TestAction::assert_eq("Boolean().toString()", "[object Boolean]"),
TestAction::assert_eq("(() => {}).toString()", js_string!("[object Function]")), TestAction::assert_eq("Number(42).toString()", "[object Number]"),
TestAction::assert_eq("(new Error('')).toString()", js_string!("[object Error]")), TestAction::assert_eq("String('boa').toString()", "[object String]"),
TestAction::assert_eq("Boolean().toString()", js_string!("[object Boolean]")), TestAction::assert_eq("(new Date()).toString()", "[object Date]"),
TestAction::assert_eq("Number(42).toString()", js_string!("[object Number]")), TestAction::assert_eq("/boa/.toString()", "[object RegExp]"),
TestAction::assert_eq("String('boa').toString()", js_string!("[object String]")), TestAction::assert_eq("({}).toString()", "[object Object]"),
TestAction::assert_eq("(new Date()).toString()", js_string!("[object Date]")),
TestAction::assert_eq("/boa/.toString()", js_string!("[object RegExp]")),
TestAction::assert_eq("({}).toString()", js_string!("[object Object]")),
]); ]);
} }
@ -163,7 +160,7 @@ fn define_symbol_property() {
let sym = Symbol("key"); let sym = Symbol("key");
Object.defineProperty(obj, sym, { value: "val" }); Object.defineProperty(obj, sym, { value: "val" });
"#}), "#}),
TestAction::assert_eq("obj[sym]", js_string!("val")), TestAction::assert_eq("obj[sym]", "val"),
]); ]);
} }

17
boa_engine/src/builtins/promise/mod.rs

@ -9,7 +9,6 @@ use crate::{
context::intrinsics::{Intrinsics, StandardConstructor, StandardConstructors}, context::intrinsics::{Intrinsics, StandardConstructor, StandardConstructors},
error::JsNativeError, error::JsNativeError,
job::{JobCallback, NativeJob}, job::{JobCallback, NativeJob},
js_string,
native_function::NativeFunction, native_function::NativeFunction,
object::{ object::{
internal_methods::get_prototype_from_constructor, FunctionObjectBuilder, JsFunction, internal_methods::get_prototype_from_constructor, FunctionObjectBuilder, JsFunction,
@ -901,12 +900,8 @@ impl Promise {
let obj = JsObject::with_object_proto(context.intrinsics()); let obj = JsObject::with_object_proto(context.intrinsics());
// 10. Perform ! CreateDataPropertyOrThrow(obj, "status", "fulfilled"). // 10. Perform ! CreateDataPropertyOrThrow(obj, "status", "fulfilled").
obj.create_data_property_or_throw( obj.create_data_property_or_throw("status", "fulfilled", context)
"status", .expect("cannot fail per spec");
js_string!("fulfilled"),
context,
)
.expect("cannot fail per spec");
// 11. Perform ! CreateDataPropertyOrThrow(obj, "value", x). // 11. Perform ! CreateDataPropertyOrThrow(obj, "value", x).
obj.create_data_property_or_throw( obj.create_data_property_or_throw(
@ -991,12 +986,8 @@ impl Promise {
let obj = JsObject::with_object_proto(context.intrinsics()); let obj = JsObject::with_object_proto(context.intrinsics());
// 10. Perform ! CreateDataPropertyOrThrow(obj, "status", "rejected"). // 10. Perform ! CreateDataPropertyOrThrow(obj, "status", "rejected").
obj.create_data_property_or_throw( obj.create_data_property_or_throw("status", "rejected", context)
"status", .expect("cannot fail per spec");
js_string!("rejected"),
context,
)
.expect("cannot fail per spec");
// 11. Perform ! CreateDataPropertyOrThrow(obj, "reason", x). // 11. Perform ! CreateDataPropertyOrThrow(obj, "reason", x).
obj.create_data_property_or_throw( obj.create_data_property_or_throw(

9
boa_engine/src/builtins/reflect/tests.rs

@ -1,4 +1,4 @@
use crate::{js_string, run_test_actions, JsValue, TestAction}; use crate::{run_test_actions, JsValue, TestAction};
use indoc::indoc; use indoc::indoc;
#[test] #[test]
@ -68,10 +68,7 @@ fn get_prototype_of() {
function F() { this.p = 42 }; function F() { this.p = 42 };
let f = new F(); let f = new F();
"#}), "#}),
TestAction::assert_eq( TestAction::assert_eq("Reflect.getPrototypeOf(f).constructor.name", "F"),
"Reflect.getPrototypeOf(f).constructor.name",
js_string!("F"),
),
]); ]);
} }
@ -134,6 +131,6 @@ fn set_prototype_of() {
let obj = {} let obj = {}
Reflect.setPrototypeOf(obj, F); Reflect.setPrototypeOf(obj, F);
"#}), "#}),
TestAction::assert_eq("Reflect.getPrototypeOf(obj).name", js_string!("F")), TestAction::assert_eq("Reflect.getPrototypeOf(obj).name", "F"),
]); ]);
} }

6
boa_engine/src/builtins/regexp/mod.rs

@ -652,7 +652,7 @@ impl RegExp {
this, this,
&JsValue::new(context.intrinsics().constructors().regexp().prototype()), &JsValue::new(context.intrinsics().constructors().regexp().prototype()),
) { ) {
Ok(JsValue::new(js_string!("(?:)"))) Ok(JsValue::new("(?:)"))
} else { } else {
Err(JsNativeError::typ() Err(JsNativeError::typ()
.with_message("RegExp.prototype.source method called on incompatible value") .with_message("RegExp.prototype.source method called on incompatible value")
@ -680,7 +680,7 @@ impl RegExp {
/// [spec]: https://tc39.es/ecma262/#sec-escaperegexppattern /// [spec]: https://tc39.es/ecma262/#sec-escaperegexppattern
fn escape_pattern(src: &JsString, _flags: &JsString) -> JsValue { fn escape_pattern(src: &JsString, _flags: &JsString) -> JsValue {
if src.is_empty() { if src.is_empty() {
js_string!("(?:)").into() "(?:)".into()
} else { } else {
let mut s = Vec::with_capacity(src.len()); let mut s = Vec::with_capacity(src.len());
let mut buf = [0; 2]; let mut buf = [0; 2];
@ -1850,7 +1850,7 @@ impl RegExp {
.expect("already checked that the object was a RegExp") = regexp; .expect("already checked that the object was a RegExp") = regexp;
} }
this.set(utf16!("lastIndex"), 0, true, context)?; this.set("lastIndex", 0, true, context)?;
Ok(this.into()) Ok(this.into())
} }

3
boa_engine/src/builtins/regexp/regexp_string_iterator.rs

@ -14,7 +14,6 @@ use crate::{
builtins::{iterable::create_iter_result_object, regexp, BuiltInBuilder, IntrinsicObject}, builtins::{iterable::create_iter_result_object, regexp, BuiltInBuilder, IntrinsicObject},
context::intrinsics::Intrinsics, context::intrinsics::Intrinsics,
error::JsNativeError, error::JsNativeError,
js_string,
object::{JsObject, ObjectData}, object::{JsObject, ObjectData},
property::Attribute, property::Attribute,
realm::Realm, realm::Realm,
@ -55,7 +54,7 @@ impl IntrinsicObject for RegExpStringIterator {
.static_method(Self::next, "next", 0) .static_method(Self::next, "next", 0)
.static_property( .static_property(
JsSymbol::to_string_tag(), JsSymbol::to_string_tag(),
js_string!("RegExp String Iterator"), "RegExp String Iterator",
Attribute::CONFIGURABLE, Attribute::CONFIGURABLE,
) )
.build(); .build();

16
boa_engine/src/builtins/regexp/tests.rs

@ -35,7 +35,7 @@ fn species() {
// return-value // return-value
TestAction::assert("Object.is(accessor.call(thisVal), thisVal)"), TestAction::assert("Object.is(accessor.call(thisVal), thisVal)"),
// symbol-species-name // symbol-species-name
TestAction::assert_eq("name.value", js_string!("get [Symbol.species]")), TestAction::assert_eq("name.value", "get [Symbol.species]"),
TestAction::assert("!name.enumerable"), TestAction::assert("!name.enumerable"),
TestAction::assert("!name.writable"), TestAction::assert("!name.writable"),
TestAction::assert("name.configurable"), TestAction::assert("name.configurable"),
@ -63,7 +63,7 @@ fn flags() {
TestAction::assert("!re_gi.dotAll"), TestAction::assert("!re_gi.dotAll"),
TestAction::assert("!re_gi.unicode"), TestAction::assert("!re_gi.unicode"),
TestAction::assert("!re_gi.sticky"), TestAction::assert("!re_gi.sticky"),
TestAction::assert_eq("re_gi.flags", js_string!("gi")), TestAction::assert_eq("re_gi.flags", "gi"),
// //
TestAction::assert("!re_sm.global"), TestAction::assert("!re_sm.global"),
TestAction::assert("!re_sm.ignoreCase"), TestAction::assert("!re_sm.ignoreCase"),
@ -71,7 +71,7 @@ fn flags() {
TestAction::assert("re_sm.dotAll"), TestAction::assert("re_sm.dotAll"),
TestAction::assert("!re_sm.unicode"), TestAction::assert("!re_sm.unicode"),
TestAction::assert("!re_sm.sticky"), TestAction::assert("!re_sm.sticky"),
TestAction::assert_eq("re_sm.flags", js_string!("ms")), TestAction::assert_eq("re_sm.flags", "ms"),
// //
TestAction::assert("!re_u.global"), TestAction::assert("!re_u.global"),
TestAction::assert("!re_u.ignoreCase"), TestAction::assert("!re_u.ignoreCase"),
@ -79,7 +79,7 @@ fn flags() {
TestAction::assert("!re_u.dotAll"), TestAction::assert("!re_u.dotAll"),
TestAction::assert("re_u.unicode"), TestAction::assert("re_u.unicode"),
TestAction::assert("!re_u.sticky"), TestAction::assert("!re_u.sticky"),
TestAction::assert_eq("re_u.flags", js_string!("u")), TestAction::assert_eq("re_u.flags", "u"),
]); ]);
} }
@ -112,7 +112,7 @@ fn exec() {
TestAction::assert_eq("result.index", 4), TestAction::assert_eq("result.index", 4),
TestAction::assert_eq( TestAction::assert_eq(
"result.input", "result.input",
js_string!("The Quick Brown Fox Jumps Over The Lazy Dog"), "The Quick Brown Fox Jumps Over The Lazy Dog",
), ),
]); ]);
} }
@ -136,8 +136,8 @@ fn no_panic_on_parse_fail() {
#[test] #[test]
fn to_string() { fn to_string() {
run_test_actions([ run_test_actions([
TestAction::assert_eq("(new RegExp('a+b+c')).toString()", js_string!("/a+b+c/")), TestAction::assert_eq("(new RegExp('a+b+c')).toString()", "/a+b+c/"),
TestAction::assert_eq("(new RegExp('bar', 'g')).toString()", js_string!("/bar/g")), TestAction::assert_eq("(new RegExp('bar', 'g')).toString()", "/bar/g"),
TestAction::assert_eq(r"(new RegExp('\\n', 'g')).toString()", js_string!(r"/\n/g")), TestAction::assert_eq(r"(new RegExp('\\n', 'g')).toString()", js_string!(r"/\n/g")),
TestAction::assert_eq(r"/\n/g.toString()", js_string!(r"/\n/g")), TestAction::assert_eq(r"/\n/g.toString()", js_string!(r"/\n/g")),
TestAction::assert_eq(r"/,\;/.toString()", js_string!(r"/,\;/")), TestAction::assert_eq(r"/,\;/.toString()", js_string!(r"/,\;/")),
@ -162,7 +162,7 @@ fn search() {
TestAction::assert("!length.writable"), TestAction::assert("!length.writable"),
TestAction::assert("length.configurable"), TestAction::assert("length.configurable"),
// name // name
TestAction::assert_eq("name.value", js_string!("[Symbol.search]")), TestAction::assert_eq("name.value", "[Symbol.search]"),
TestAction::assert("!name.enumerable"), TestAction::assert("!name.enumerable"),
TestAction::assert("!name.writable"), TestAction::assert("!name.writable"),
TestAction::assert("name.configurable"), TestAction::assert("name.configurable"),

3
boa_engine/src/builtins/set/set_iterator.rs

@ -12,7 +12,6 @@ use crate::{
}, },
context::intrinsics::Intrinsics, context::intrinsics::Intrinsics,
error::JsNativeError, error::JsNativeError,
js_string,
object::{JsObject, ObjectData}, object::{JsObject, ObjectData},
property::{Attribute, PropertyNameKind}, property::{Attribute, PropertyNameKind},
realm::Realm, realm::Realm,
@ -52,7 +51,7 @@ impl IntrinsicObject for SetIterator {
.static_method(Self::next, "next", 0) .static_method(Self::next, "next", 0)
.static_property( .static_property(
JsSymbol::to_string_tag(), JsSymbol::to_string_tag(),
js_string!("Set Iterator"), "Set Iterator",
Attribute::CONFIGURABLE, Attribute::CONFIGURABLE,
) )
.build(); .build();

2
boa_engine/src/builtins/string/mod.rs

@ -2091,7 +2091,7 @@ impl String {
let s = o.to_string(context)?; let s = o.to_string(context)?;
// 4. Let rx be ? RegExpCreate(regexp, "g"). // 4. Let rx be ? RegExpCreate(regexp, "g").
let rx = RegExp::create(regexp, &JsValue::new(js_string!("g")), context)?; let rx = RegExp::create(regexp, &JsValue::new("g"), context)?;
// 5. Return ? Invoke(rx, @@matchAll, « S »). // 5. Return ? Invoke(rx, @@matchAll, « S »).
rx.invoke(JsSymbol::match_all(), &[JsValue::new(s)], context) rx.invoke(JsSymbol::match_all(), &[JsValue::new(s)], context)

2
boa_engine/src/builtins/string/string_iterator.rs

@ -46,7 +46,7 @@ impl IntrinsicObject for StringIterator {
.static_method(Self::next, "next", 0) .static_method(Self::next, "next", 0)
.static_property( .static_property(
JsSymbol::to_string_tag(), JsSymbol::to_string_tag(),
js_string!("String Iterator"), "String Iterator",
Attribute::CONFIGURABLE, Attribute::CONFIGURABLE,
) )
.build(); .build();

115
boa_engine/src/builtins/string/tests.rs

@ -56,12 +56,9 @@ fn concat() {
"#}), "#}),
TestAction::assert_eq( TestAction::assert_eq(
"hello.concat(world, nice)", "hello.concat(world, nice)",
js_string!("Hello, world! Have a nice day."), "Hello, world! Have a nice day.",
),
TestAction::assert_eq(
"hello + world + nice",
js_string!("Hello, world! Have a nice day."),
), ),
TestAction::assert_eq("hello + world + nice", "Hello, world! Have a nice day."),
]); ]);
} }
@ -72,10 +69,7 @@ fn generic_concat() {
Number.prototype.concat = String.prototype.concat; Number.prototype.concat = String.prototype.concat;
let number = new Number(100); let number = new Number(100);
"#}), "#}),
TestAction::assert_eq( TestAction::assert_eq("number.concat(' - 50', ' = 50')", "100 - 50 = 50"),
"number.concat(' - 50', ' = 50')",
js_string!("100 - 50 = 50"),
),
]); ]);
} }
@ -100,8 +94,8 @@ fn repeat() {
TestAction::assert_eq("empty.repeat(1)", js_string!()), TestAction::assert_eq("empty.repeat(1)", js_string!()),
TestAction::assert_eq("en.repeat(0)", js_string!()), TestAction::assert_eq("en.repeat(0)", js_string!()),
TestAction::assert_eq("zh.repeat(0)", js_string!()), TestAction::assert_eq("zh.repeat(0)", js_string!()),
TestAction::assert_eq("en.repeat(1)", js_string!("english")), TestAction::assert_eq("en.repeat(1)", "english"),
TestAction::assert_eq("zh.repeat(2)", js_string!("中文中文")), TestAction::assert_eq("zh.repeat(2)", "中文中文"),
]); ]);
} }
@ -140,9 +134,9 @@ fn repeat_generic() {
run_test_actions([ run_test_actions([
TestAction::run("Number.prototype.repeat = String.prototype.repeat;"), TestAction::run("Number.prototype.repeat = String.prototype.repeat;"),
TestAction::assert_eq("(0).repeat(0)", js_string!()), TestAction::assert_eq("(0).repeat(0)", js_string!()),
TestAction::assert_eq("(1).repeat(1)", js_string!("1")), TestAction::assert_eq("(1).repeat(1)", "1"),
TestAction::assert_eq("(1).repeat(5)", js_string!("11111")), TestAction::assert_eq("(1).repeat(5)", "11111"),
TestAction::assert_eq("(12).repeat(3)", js_string!("121212")), TestAction::assert_eq("(12).repeat(3)", "121212"),
]); ]);
} }
@ -152,7 +146,7 @@ fn replace() {
indoc! {r#" indoc! {r#"
"abc".replace("a", "2") "abc".replace("a", "2")
"#}, "#},
js_string!("2bc"), "2bc",
)]); )]);
} }
@ -162,7 +156,7 @@ fn replace_no_match() {
indoc! {r#" indoc! {r#"
"abc".replace(/d/, "$&$&") "abc".replace(/d/, "$&$&")
"#}, "#},
js_string!("abc"), "abc",
)]); )]);
} }
@ -172,7 +166,7 @@ fn replace_with_capture_groups() {
indoc! {r#" indoc! {r#"
"John Smith".replace(/(\w+)\s(\w+)/, '$2, $1') "John Smith".replace(/(\w+)\s(\w+)/, '$2, $1')
"#}, "#},
js_string!("Smith, John"), "Smith, John",
)]); )]);
} }
@ -183,7 +177,7 @@ fn replace_with_tenth_capture_group() {
var re = /(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)/; var re = /(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)/;
"0123456789".replace(re, '$10') "0123456789".replace(re, '$10')
"#}, "#},
js_string!("9"), "9",
)]); )]);
} }
@ -199,11 +193,11 @@ fn replace_substitutions() {
var end = a.replace(re, " $' "); var end = a.replace(re, " $' ");
var no_sub = a.replace(re, " $_ "); var no_sub = a.replace(re, " $_ ");
"#}), "#}),
TestAction::assert_eq("a.replace(re, \" $$ \")", js_string!("one $ three")), TestAction::assert_eq("a.replace(re, \" $$ \")", "one $ three"),
TestAction::assert_eq("a.replace(re, \"$&$&\")", js_string!("one two two three")), TestAction::assert_eq("a.replace(re, \"$&$&\")", "one two two three"),
TestAction::assert_eq("a.replace(re, \" $` \")", js_string!("one one three")), TestAction::assert_eq("a.replace(re, \" $` \")", "one one three"),
TestAction::assert_eq("a.replace(re, \" $' \")", js_string!("one three three")), TestAction::assert_eq("a.replace(re, \" $' \")", "one three three"),
TestAction::assert_eq("a.replace(re, \" $_ \")", js_string!("one $_ three")), TestAction::assert_eq("a.replace(re, \" $_ \")", "one $_ three"),
]); ]);
} }
@ -222,11 +216,11 @@ fn replace_with_function() {
"#}), "#}),
TestAction::assert_eq( TestAction::assert_eq(
"\"ecmascript is cool\".replace(/c(o)(o)(l)/, replacer)", "\"ecmascript is cool\".replace(/c(o)(o)(l)/, replacer)",
js_string!("ecmascript is awesome!"), "ecmascript is awesome!",
), ),
TestAction::assert_eq("p1", js_string!("o")), TestAction::assert_eq("p1", "o"),
TestAction::assert_eq("p2", js_string!("o")), TestAction::assert_eq("p2", "o"),
TestAction::assert_eq("p3", js_string!("l")), TestAction::assert_eq("p3", "l"),
TestAction::assert_eq("length", 14), TestAction::assert_eq("length", 14),
]); ]);
} }
@ -329,7 +323,7 @@ fn match_all_one() {
) )
"#}), "#}),
TestAction::assert_eq("m1.value.index", 0), TestAction::assert_eq("m1.value.index", 0),
TestAction::assert_eq("m1.value.input", js_string!("test1test2")), TestAction::assert_eq("m1.value.input", "test1test2"),
TestAction::assert_eq("m1.value.groups", JsValue::undefined()), TestAction::assert_eq("m1.value.groups", JsValue::undefined()),
TestAction::assert(indoc! {r#" TestAction::assert(indoc! {r#"
arrayEquals( arrayEquals(
@ -338,7 +332,7 @@ fn match_all_one() {
) )
"#}), "#}),
TestAction::assert_eq("m2.value.index", 5), TestAction::assert_eq("m2.value.index", 5),
TestAction::assert_eq("m2.value.input", js_string!("test1test2")), TestAction::assert_eq("m2.value.input", "test1test2"),
TestAction::assert_eq("m2.value.groups", JsValue::undefined()), TestAction::assert_eq("m2.value.groups", JsValue::undefined()),
TestAction::assert_eq("m3.value", JsValue::undefined()), TestAction::assert_eq("m3.value", JsValue::undefined()),
]); ]);
@ -366,7 +360,7 @@ fn match_all_two() {
) )
"#}), "#}),
TestAction::assert_eq("m1.value.index", 6), TestAction::assert_eq("m1.value.index", 6),
TestAction::assert_eq("m1.value.input", js_string!("table football, foosball")), TestAction::assert_eq("m1.value.input", "table football, foosball"),
TestAction::assert_eq("m1.value.groups", JsValue::undefined()), TestAction::assert_eq("m1.value.groups", JsValue::undefined()),
TestAction::assert(indoc! {r#" TestAction::assert(indoc! {r#"
arrayEquals( arrayEquals(
@ -375,7 +369,7 @@ fn match_all_two() {
) )
"#}), "#}),
TestAction::assert_eq("m2.value.index", 16), TestAction::assert_eq("m2.value.index", 16),
TestAction::assert_eq("m2.value.input", js_string!("table football, foosball")), TestAction::assert_eq("m2.value.input", "table football, foosball"),
TestAction::assert_eq("m2.value.groups", JsValue::undefined()), TestAction::assert_eq("m2.value.groups", JsValue::undefined()),
TestAction::assert_eq("m3.value", JsValue::undefined()), TestAction::assert_eq("m3.value", JsValue::undefined()),
]); ]);
@ -401,7 +395,7 @@ fn test_match() {
TestAction::assert_eq("result1.index", 4), TestAction::assert_eq("result1.index", 4),
TestAction::assert_eq( TestAction::assert_eq(
"result1.input", "result1.input",
js_string!("The Quick Brown Fox Jumps Over The Lazy Dog"), "The Quick Brown Fox Jumps Over The Lazy Dog",
), ),
TestAction::assert(indoc! {r#" TestAction::assert(indoc! {r#"
arrayEquals( arrayEquals(
@ -418,7 +412,7 @@ fn test_match() {
TestAction::assert_eq("result3.index", 0), TestAction::assert_eq("result3.index", 0),
TestAction::assert_eq( TestAction::assert_eq(
"result3.input", "result3.input",
js_string!("The Quick Brown Fox Jumps Over The Lazy Dog"), "The Quick Brown Fox Jumps Over The Lazy Dog",
), ),
TestAction::assert(indoc! {r#" TestAction::assert(indoc! {r#"
arrayEquals( arrayEquals(
@ -432,30 +426,30 @@ fn test_match() {
#[test] #[test]
fn trim() { fn trim() {
run_test_actions([ run_test_actions([
TestAction::assert_eq(r"'Hello'.trim()", js_string!("Hello")), TestAction::assert_eq(r"'Hello'.trim()", "Hello"),
TestAction::assert_eq(r"' \nHello'.trim()", js_string!("Hello")), TestAction::assert_eq(r"' \nHello'.trim()", "Hello"),
TestAction::assert_eq(r"'Hello \n\r'.trim()", js_string!("Hello")), TestAction::assert_eq(r"'Hello \n\r'.trim()", "Hello"),
TestAction::assert_eq(r"' Hello '.trim()", js_string!("Hello")), TestAction::assert_eq(r"' Hello '.trim()", "Hello"),
]); ]);
} }
#[test] #[test]
fn trim_start() { fn trim_start() {
run_test_actions([ run_test_actions([
TestAction::assert_eq(r"'Hello'.trimStart()", js_string!("Hello")), TestAction::assert_eq(r"'Hello'.trimStart()", "Hello"),
TestAction::assert_eq(r"' \nHello'.trimStart()", js_string!("Hello")), TestAction::assert_eq(r"' \nHello'.trimStart()", "Hello"),
TestAction::assert_eq(r"'Hello \n\r'.trimStart()", js_string!("Hello \n\r")), TestAction::assert_eq(r"'Hello \n\r'.trimStart()", "Hello \n\r"),
TestAction::assert_eq(r"' Hello '.trimStart()", js_string!("Hello ")), TestAction::assert_eq(r"' Hello '.trimStart()", "Hello "),
]); ]);
} }
#[test] #[test]
fn trim_end() { fn trim_end() {
run_test_actions([ run_test_actions([
TestAction::assert_eq(r"'Hello'.trimEnd()", js_string!("Hello")), TestAction::assert_eq(r"'Hello'.trimEnd()", "Hello"),
TestAction::assert_eq(r"' \nHello'.trimEnd()", js_string!(" \nHello")), TestAction::assert_eq(r"' \nHello'.trimEnd()", " \nHello"),
TestAction::assert_eq(r"'Hello \n\r'.trimEnd()", js_string!("Hello")), TestAction::assert_eq(r"'Hello \n\r'.trimEnd()", "Hello"),
TestAction::assert_eq(r"' Hello '.trimEnd()", js_string!(" Hello")), TestAction::assert_eq(r"' Hello '.trimEnd()", " Hello"),
]); ]);
} }
@ -578,7 +572,7 @@ fn split_with_symbol_split_method() {
sep_a[Symbol.split] = function(s, limit) { return s + limit.toString(); }; sep_a[Symbol.split] = function(s, limit) { return s + limit.toString(); };
'hello'.split(sep_a, 10) 'hello'.split(sep_a, 10)
"#}, "#},
js_string!("hello10"), "hello10",
), ),
TestAction::assert(indoc! {r#" TestAction::assert(indoc! {r#"
let sep_b = {}; let sep_b = {};
@ -752,10 +746,10 @@ fn last_index_non_integer_position_argument() {
fn char_at() { fn char_at() {
run_test_actions([ run_test_actions([
TestAction::assert_eq("'abc'.charAt(-1)", js_string!()), TestAction::assert_eq("'abc'.charAt(-1)", js_string!()),
TestAction::assert_eq("'abc'.charAt(1)", js_string!("b")), TestAction::assert_eq("'abc'.charAt(1)", "b"),
TestAction::assert_eq("'abc'.charAt(9)", js_string!()), TestAction::assert_eq("'abc'.charAt(9)", js_string!()),
TestAction::assert_eq("'abc'.charAt()", js_string!("a")), TestAction::assert_eq("'abc'.charAt()", "a"),
TestAction::assert_eq("'abc'.charAt(null)", js_string!("a")), TestAction::assert_eq("'abc'.charAt(null)", "a"),
TestAction::assert_eq(r"'\uDBFF'.charAt(0)", js_string!(&[0xDBFFu16])), TestAction::assert_eq(r"'\uDBFF'.charAt(0)", js_string!(&[0xDBFFu16])),
]); ]);
} }
@ -794,10 +788,10 @@ fn code_point_at() {
#[test] #[test]
fn slice() { fn slice() {
run_test_actions([ run_test_actions([
TestAction::assert_eq("'abc'.slice()", js_string!("abc")), TestAction::assert_eq("'abc'.slice()", "abc"),
TestAction::assert_eq("'abc'.slice(1)", js_string!("bc")), TestAction::assert_eq("'abc'.slice(1)", "bc"),
TestAction::assert_eq("'abc'.slice(-1)", js_string!("c")), TestAction::assert_eq("'abc'.slice(-1)", "c"),
TestAction::assert_eq("'abc'.slice(0, 9)", js_string!("abc")), TestAction::assert_eq("'abc'.slice(0, 9)", "abc"),
TestAction::assert_eq("'abc'.slice(9, 10)", js_string!()), TestAction::assert_eq("'abc'.slice(9, 10)", js_string!()),
]); ]);
} }
@ -844,8 +838,8 @@ fn unicode_iter() {
fn string_get_property() { fn string_get_property() {
run_test_actions([ run_test_actions([
TestAction::assert_eq("'abc'[-1]", JsValue::undefined()), TestAction::assert_eq("'abc'[-1]", JsValue::undefined()),
TestAction::assert_eq("'abc'[1]", js_string!("b")), TestAction::assert_eq("'abc'[1]", "b"),
TestAction::assert_eq("'abc'[2]", js_string!("c")), TestAction::assert_eq("'abc'[2]", "c"),
TestAction::assert_eq("'abc'[3]", JsValue::undefined()), TestAction::assert_eq("'abc'[3]", JsValue::undefined()),
TestAction::assert_eq("'abc'['foo']", JsValue::undefined()), TestAction::assert_eq("'abc'['foo']", JsValue::undefined()),
TestAction::assert_eq("'😀'[0]", js_string!(&[0xD83D])), TestAction::assert_eq("'😀'[0]", js_string!(&[0xD83D])),
@ -866,9 +860,9 @@ fn search() {
fn from_code_point() { fn from_code_point() {
// Taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint // Taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint
run_test_actions([ run_test_actions([
TestAction::assert_eq("String.fromCodePoint(42)", js_string!("*")), TestAction::assert_eq("String.fromCodePoint(42)", "*"),
TestAction::assert_eq("String.fromCodePoint(65, 90)", js_string!("AZ")), TestAction::assert_eq("String.fromCodePoint(65, 90)", "AZ"),
TestAction::assert_eq("String.fromCodePoint(0x404)", js_string!("Є")), TestAction::assert_eq("String.fromCodePoint(0x404)", "Є"),
TestAction::assert_eq( TestAction::assert_eq(
"String.fromCodePoint(0x2f804)", "String.fromCodePoint(0x2f804)",
js_string!(&[0xD87E, 0xDC04]), js_string!(&[0xD87E, 0xDC04]),
@ -882,10 +876,7 @@ fn from_code_point() {
"String.fromCharCode(0xD800, 0xD8FF)", "String.fromCharCode(0xD800, 0xD8FF)",
js_string!(&[0xD800, 0xD8FF]), js_string!(&[0xD800, 0xD8FF]),
), ),
TestAction::assert_eq( TestAction::assert_eq("String.fromCodePoint(9731, 9733, 9842, 0x4F60)", "☃★♲你"),
"String.fromCodePoint(9731, 9733, 9842, 0x4F60)",
js_string!("☃★♲你"),
),
TestAction::assert_native_error( TestAction::assert_native_error(
"String.fromCodePoint('_')", "String.fromCodePoint('_')",
JsNativeErrorKind::Range, JsNativeErrorKind::Range,

4
boa_engine/src/builtins/symbol/tests.rs

@ -1,4 +1,4 @@
use crate::{js_string, run_test_actions, JsValue, TestAction}; use crate::{run_test_actions, JsValue, TestAction};
use indoc::indoc; use indoc::indoc;
#[test] #[test]
@ -12,7 +12,7 @@ fn call_symbol_and_check_return_type() {
fn print_symbol_expect_description() { fn print_symbol_expect_description() {
run_test_actions([TestAction::assert_eq( run_test_actions([TestAction::assert_eq(
"String(Symbol('Hello'))", "String(Symbol('Hello'))",
js_string!("Symbol(Hello)"), "Symbol(Hello)",
)]); )]);
} }

4
boa_engine/src/builtins/temporal/calendar/tests.rs

@ -1,11 +1,11 @@
use crate::{js_string, run_test_actions, TestAction}; use crate::{run_test_actions, TestAction};
#[test] #[test]
fn calendar_constructor() { fn calendar_constructor() {
// TODO: Add other BuiltinCalendars // TODO: Add other BuiltinCalendars
run_test_actions([TestAction::assert_eq( run_test_actions([TestAction::assert_eq(
"new Temporal.Calendar('iso8601').id", "new Temporal.Calendar('iso8601').id",
js_string!("iso8601"), "iso8601",
)]); )]);
} }

14
boa_engine/src/builtins/temporal/duration/record.rs

@ -9,7 +9,7 @@ use crate::{
round_number_to_increment, to_temporal_date, NS_PER_DAY, round_number_to_increment, to_temporal_date, NS_PER_DAY,
}, },
}, },
js_string, Context, JsNativeError, JsObject, JsResult, JsValue, Context, JsNativeError, JsObject, JsResult, JsValue,
}; };
use super::super::{ use super::super::{
@ -1121,11 +1121,7 @@ impl DurationRecord {
// n. Let untilOptions be OrdinaryObjectCreate(null). // n. Let untilOptions be OrdinaryObjectCreate(null).
let until_options = JsObject::with_null_proto(); let until_options = JsObject::with_null_proto();
// o. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "month"). // o. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "month").
until_options.create_data_property_or_throw( until_options.create_data_property_or_throw("largestUnit", "month", context)?;
"largestUnit",
js_string!("month"),
context,
)?;
// p. Let untilResult be ? CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil). // p. Let untilResult be ? CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil).
let until_result = calendar::calendar_date_until( let until_result = calendar::calendar_date_until(
@ -1161,11 +1157,7 @@ impl DurationRecord {
// v. Set untilOptions to OrdinaryObjectCreate(null). // v. Set untilOptions to OrdinaryObjectCreate(null).
let until_options = JsObject::with_null_proto(); let until_options = JsObject::with_null_proto();
// vi. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "month"). // vi. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "month").
until_options.create_data_property_or_throw( until_options.create_data_property_or_throw("largestUnit", "month", context)?;
"largestUnit",
js_string!("month"),
context,
)?;
// vii. Set untilResult to ? CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil). // vii. Set untilResult to ? CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil).
let until_result = calendar::calendar_date_until( let until_result = calendar::calendar_date_until(
calendar, calendar,

2
boa_engine/src/builtins/temporal/plain_date/mod.rs

@ -219,7 +219,7 @@ impl BuiltInConstructor for PlainDate {
let iso_year = super::to_integer_with_truncation(args.get_or_undefined(0), context)?; let iso_year = super::to_integer_with_truncation(args.get_or_undefined(0), context)?;
let iso_month = super::to_integer_with_truncation(args.get_or_undefined(1), context)?; let iso_month = super::to_integer_with_truncation(args.get_or_undefined(1), context)?;
let iso_day = super::to_integer_with_truncation(args.get_or_undefined(2), context)?; let iso_day = super::to_integer_with_truncation(args.get_or_undefined(2), context)?;
let default_calendar = JsValue::from(js_string!("iso8601")); let default_calendar = JsValue::from("iso8601");
let calendar_like = args.get(3).unwrap_or(&default_calendar); let calendar_like = args.get(3).unwrap_or(&default_calendar);
let iso = IsoDateRecord::new(iso_year, iso_month, iso_day); let iso = IsoDateRecord::new(iso_year, iso_month, iso_day);

8
boa_engine/src/builtins/temporal/plain_year_month/mod.rs

@ -3,7 +3,6 @@
use crate::{ use crate::{
builtins::{BuiltInBuilder, BuiltInConstructor, BuiltInObject, IntrinsicObject}, builtins::{BuiltInBuilder, BuiltInConstructor, BuiltInObject, IntrinsicObject},
context::intrinsics::{Intrinsics, StandardConstructor, StandardConstructors}, context::intrinsics::{Intrinsics, StandardConstructor, StandardConstructors},
js_string,
object::{internal_methods::get_prototype_from_constructor, ObjectData}, object::{internal_methods::get_prototype_from_constructor, ObjectData},
property::Attribute, property::Attribute,
realm::Realm, realm::Realm,
@ -158,12 +157,7 @@ impl BuiltInConstructor for PlainYearMonth {
// 7. Return ? CreateTemporalYearMonth(y, m, calendar, ref, NewTarget). // 7. Return ? CreateTemporalYearMonth(y, m, calendar, ref, NewTarget).
let record = IsoDateRecord::new(y, m, ref_day); let record = IsoDateRecord::new(y, m, ref_day);
create_temporal_year_month( create_temporal_year_month(record, JsValue::from("iso8601"), Some(new_target), context)
record,
JsValue::from(js_string!("iso8601")),
Some(new_target),
context,
)
} }
} }

8
boa_engine/src/builtins/temporal/tests.rs

@ -1,5 +1,5 @@
use super::date_equations::{epoch_time_to_month_in_year, mathematical_in_leap_year}; use super::date_equations::{epoch_time_to_month_in_year, mathematical_in_leap_year};
use crate::{js_string, run_test_actions, JsValue, TestAction}; use crate::{run_test_actions, JsValue, TestAction};
// Temporal Object tests. // Temporal Object tests.
@ -9,9 +9,9 @@ fn temporal_object() {
run_test_actions([ run_test_actions([
TestAction::assert_eq( TestAction::assert_eq(
"Object.prototype.toString.call(Temporal)", "Object.prototype.toString.call(Temporal)",
js_string!("[object Temporal]"), "[object Temporal]",
), ),
TestAction::assert_eq("String(Temporal)", js_string!("[object Temporal]")), TestAction::assert_eq("String(Temporal)", "[object Temporal]"),
TestAction::assert_eq("Object.keys(Temporal).length === 0", true), TestAction::assert_eq("Object.keys(Temporal).length === 0", true),
]); ]);
} }
@ -23,7 +23,7 @@ fn now_object() {
TestAction::assert_eq("Object.isExtensible(Temporal.Now)", true), TestAction::assert_eq("Object.isExtensible(Temporal.Now)", true),
TestAction::assert_eq( TestAction::assert_eq(
"Object.prototype.toString.call(Temporal.Now)", "Object.prototype.toString.call(Temporal.Now)",
js_string!("[object Temporal.Now]"), "[object Temporal.Now]",
), ),
TestAction::assert_eq( TestAction::assert_eq(
"Object.getPrototypeOf(Temporal.Now) === Object.prototype", "Object.getPrototypeOf(Temporal.Now) === Object.prototype",

3
boa_engine/src/builtins/weak/weak_ref.rs

@ -4,7 +4,6 @@ use boa_profiler::Profiler;
use crate::{ use crate::{
builtins::{BuiltInBuilder, BuiltInConstructor, BuiltInObject, IntrinsicObject}, builtins::{BuiltInBuilder, BuiltInConstructor, BuiltInObject, IntrinsicObject},
context::intrinsics::{Intrinsics, StandardConstructor, StandardConstructors}, context::intrinsics::{Intrinsics, StandardConstructor, StandardConstructors},
js_string,
object::{internal_methods::get_prototype_from_constructor, JsObject, ObjectData}, object::{internal_methods::get_prototype_from_constructor, JsObject, ObjectData},
property::Attribute, property::Attribute,
realm::Realm, realm::Realm,
@ -36,7 +35,7 @@ impl IntrinsicObject for WeakRef {
BuiltInBuilder::from_standard_constructor::<Self>(realm) BuiltInBuilder::from_standard_constructor::<Self>(realm)
.property( .property(
JsSymbol::to_string_tag(), JsSymbol::to_string_tag(),
js_string!("WeakRef"), "WeakRef",
Attribute::CONFIGURABLE, Attribute::CONFIGURABLE,
) )
.method(Self::deref, "deref", 0) .method(Self::deref, "deref", 0)

2
boa_engine/src/context/mod.rs

@ -80,7 +80,7 @@ thread_local! {
/// .property("x", 12, Attribute::READONLY) /// .property("x", 12, Attribute::READONLY)
/// .build(); /// .build();
/// context /// context
/// .register_global_property(js_string!("arg"), arg, Attribute::all()) /// .register_global_property("arg", arg, Attribute::all())
/// .expect("property shouldn't exist"); /// .expect("property shouldn't exist");
/// ///
/// let value = context.eval(Source::from_bytes("test(arg)")).unwrap(); /// let value = context.eval(Source::from_bytes("test(arg)")).unwrap();

3
boa_engine/src/module/mod.rs

@ -46,7 +46,6 @@ use boa_profiler::Profiler;
use crate::{ use crate::{
builtins::promise::{PromiseCapability, PromiseState}, builtins::promise::{PromiseCapability, PromiseState},
environments::DeclarativeEnvironment, environments::DeclarativeEnvironment,
js_string,
object::{JsObject, JsPromise, ObjectData}, object::{JsObject, JsPromise, ObjectData},
realm::Realm, realm::Realm,
Context, HostDefined, JsError, JsResult, JsString, JsValue, NativeFunction, Context, HostDefined, JsError, JsResult, JsString, JsValue, NativeFunction,
@ -615,7 +614,7 @@ impl ModuleNamespace {
// 8. Create own properties of M corresponding to the definitions in 28.3. // 8. Create own properties of M corresponding to the definitions in 28.3.
let namespace = context.intrinsics().templates().namespace().create( let namespace = context.intrinsics().templates().namespace().create(
ObjectData::module_namespace(Self { module, exports }), ObjectData::module_namespace(Self { module, exports }),
vec![js_string!("Module").into()], vec!["Module".into()],
); );
// 9. Set module.[[Namespace]] to M. // 9. Set module.[[Namespace]] to M.

2
boa_engine/src/object/builtins/jsdate.rs

@ -32,7 +32,7 @@ use crate::{
/// ///
/// assert_eq!( /// assert_eq!(
/// date.to_date_string(context)?, /// date.to_date_string(context)?,
/// JsValue::from(js_string!("Mon Dec 04 1995")) /// JsValue::from("Mon Dec 04 1995")
/// ); /// );
/// ///
/// Ok(()) /// Ok(())

46
boa_engine/src/object/builtins/jsmap.rs

@ -29,8 +29,8 @@ use std::ops::Deref;
/// let map = JsMap::new(context); /// let map = JsMap::new(context);
/// ///
/// // Set key-value pairs for the `JsMap`. /// // Set key-value pairs for the `JsMap`.
/// map.set(js_string!("Key-1"), js_string!("Value-1"), context)?; /// map.set("Key-1", "Value-1", context)?;
/// map.set(js_string!("Key-2"), 10, context)?; /// map.set("Key-2", 10, context)?;
/// ///
/// assert_eq!(map.get_size(context)?, 2.into()); /// assert_eq!(map.get_size(context)?, 2.into());
/// # Ok(()) /// # Ok(())
@ -52,8 +52,8 @@ use std::ops::Deref;
/// ///
/// // Create a `[key, value]` pair of JsValues /// // Create a `[key, value]` pair of JsValues
/// let vec_one: Vec<JsValue> = vec![ /// let vec_one: Vec<JsValue> = vec![
/// js_string!("first-key").into(), /// "first-key".into(),
/// js_string!("first-value").into() /// "first-value".into()
/// ]; /// ];
/// ///
/// // We create an push our `[key, value]` pair onto our array as a `JsArray` /// // We create an push our `[key, value]` pair onto our array as a `JsArray`
@ -63,8 +63,8 @@ use std::ops::Deref;
/// let js_iterable_map = JsMap::from_js_iterable(&js_array.into(), context)?; /// let js_iterable_map = JsMap::from_js_iterable(&js_array.into(), context)?;
/// ///
/// assert_eq!( /// assert_eq!(
/// js_iterable_map.get(js_string!("first-key"), context)?, /// js_iterable_map.get("first-key", context)?,
/// js_string!("first-value").into() /// "first-value".into()
/// ); /// );
/// ///
/// # Ok(()) /// # Ok(())
@ -111,8 +111,8 @@ impl JsMap {
/// ///
/// // Create a `[key, value]` pair of JsValues and add it to the `JsArray` as a `JsArray` /// // Create a `[key, value]` pair of JsValues and add it to the `JsArray` as a `JsArray`
/// let vec_one: Vec<JsValue> = vec![ /// let vec_one: Vec<JsValue> = vec![
/// js_string!("first-key").into(), /// "first-key".into(),
/// js_string!("first-value").into() /// "first-value".into()
/// ]; /// ];
/// js_array.push(JsArray::from_iter(vec_one, context), context)?; /// js_array.push(JsArray::from_iter(vec_one, context), context)?;
/// ///
@ -228,12 +228,12 @@ impl JsMap {
/// # let context = &mut Context::default(); /// # let context = &mut Context::default();
/// let js_map = JsMap::new(context); /// let js_map = JsMap::new(context);
/// ///
/// js_map.set(js_string!("foo"), js_string!("bar"), context)?; /// js_map.set("foo", "bar", context)?;
/// js_map.set(2, 4, context)?; /// js_map.set(2, 4, context)?;
/// ///
/// assert_eq!( /// assert_eq!(
/// js_map.get(js_string!("foo"), context)?, /// js_map.get("foo", context)?,
/// js_string!("bar").into() /// "bar".into()
/// ); /// );
/// assert_eq!(js_map.get(2, context)?, 4.into()); /// assert_eq!(js_map.get(2, context)?, 4.into());
/// # Ok(()) /// # Ok(())
@ -264,7 +264,7 @@ impl JsMap {
/// # let context = &mut Context::default(); /// # let context = &mut Context::default();
/// let js_map = JsMap::new(context); /// let js_map = JsMap::new(context);
/// ///
/// js_map.set(js_string!("foo"), js_string!("bar"), context)?; /// js_map.set("foo", "bar", context)?;
/// ///
/// let map_size = js_map.get_size(context)?; /// let map_size = js_map.get_size(context)?;
/// ///
@ -289,14 +289,14 @@ impl JsMap {
/// # fn main() -> JsResult<()> { /// # fn main() -> JsResult<()> {
/// # let context = &mut Context::default(); /// # let context = &mut Context::default();
/// let js_map = JsMap::new(context); /// let js_map = JsMap::new(context);
/// js_map.set(js_string!("foo"), js_string!("bar"), context)?; /// js_map.set("foo", "bar", context)?;
/// js_map.set(js_string!("hello"), js_string!("world"), context)?; /// js_map.set("hello", "world", context)?;
/// ///
/// js_map.delete(js_string!("foo"), context)?; /// js_map.delete("foo", context)?;
/// ///
/// assert_eq!(js_map.get_size(context)?, 1.into()); /// assert_eq!(js_map.get_size(context)?, 1.into());
/// assert_eq!( /// assert_eq!(
/// js_map.get(js_string!("foo"), context)?, /// js_map.get("foo", context)?,
/// JsValue::undefined() /// JsValue::undefined()
/// ); /// );
/// # Ok(()) /// # Ok(())
@ -321,11 +321,11 @@ impl JsMap {
/// # fn main() -> JsResult<()> { /// # fn main() -> JsResult<()> {
/// # let context = &mut Context::default(); /// # let context = &mut Context::default();
/// let js_map = JsMap::new(context); /// let js_map = JsMap::new(context);
/// js_map.set(js_string!("foo"), js_string!("bar"), context)?; /// js_map.set("foo", "bar", context)?;
/// ///
/// let retrieved_value = js_map.get(js_string!("foo"), context)?; /// let retrieved_value = js_map.get("foo", context)?;
/// ///
/// assert_eq!(retrieved_value, js_string!("bar").into()); /// assert_eq!(retrieved_value, "bar".into());
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
@ -348,8 +348,8 @@ impl JsMap {
/// # fn main() -> JsResult<()> { /// # fn main() -> JsResult<()> {
/// # let context = &mut Context::default(); /// # let context = &mut Context::default();
/// let js_map = JsMap::new(context); /// let js_map = JsMap::new(context);
/// js_map.set(js_string!("foo"), js_string!("bar"), context)?; /// js_map.set("foo", "bar", context)?;
/// js_map.set(js_string!("hello"), js_string!("world"), context)?; /// js_map.set("hello", "world", context)?;
/// ///
/// js_map.clear(context)?; /// js_map.clear(context)?;
/// ///
@ -374,9 +374,9 @@ impl JsMap {
/// # fn main() -> JsResult<()> { /// # fn main() -> JsResult<()> {
/// # let context = &mut Context::default(); /// # let context = &mut Context::default();
/// let js_map = JsMap::new(context); /// let js_map = JsMap::new(context);
/// js_map.set(js_string!("foo"), js_string!("bar"), context)?; /// js_map.set("foo", "bar", context)?;
/// ///
/// let has_key = js_map.has(js_string!("foo"), context)?; /// let has_key = js_map.has("foo", context)?;
/// ///
/// assert_eq!(has_key, true.into()); /// assert_eq!(has_key, true.into());
/// # Ok(()) /// # Ok(())

2
boa_engine/src/object/builtins/jspromise.rs

@ -35,7 +35,7 @@ use boa_gc::{Finalize, Gc, GcRefCell, Trace};
/// let context = &mut Context::default(); /// let context = &mut Context::default();
/// ///
/// context.register_global_property( /// context.register_global_property(
/// js_string!("finally"), /// "finally",
/// false, /// false,
/// Attribute::all(), /// Attribute::all(),
/// ); /// );

2
boa_engine/src/object/mod.rs

@ -2622,7 +2622,7 @@ impl<'realm> FunctionObjectBuilder<'realm> {
/// .property(1, 1, Attribute::all()) /// .property(1, 1, Attribute::all())
/// .function( /// .function(
/// NativeFunction::from_fn_ptr(|_, _, _| Ok(JsValue::undefined())), /// NativeFunction::from_fn_ptr(|_, _, _| Ok(JsValue::undefined())),
/// js_string!("func"), /// "func",
/// 0, /// 0,
/// ) /// )
/// .build(); /// .build();

20
boa_engine/src/tests/control_flow/loops.rs

@ -1,4 +1,4 @@
use crate::{js_string, run_test_actions, JsNativeErrorKind, TestAction}; use crate::{run_test_actions, JsNativeErrorKind, TestAction};
use indoc::indoc; use indoc::indoc;
#[test] #[test]
@ -87,7 +87,7 @@ fn for_loop() {
b b
} }
"#}, "#},
js_string!("hello"), "hello",
), ),
TestAction::assert_eq( TestAction::assert_eq(
indoc! {r#" indoc! {r#"
@ -192,7 +192,7 @@ fn try_break_finally_edge_cases() {
a + b a + b
"#; "#;
run_test_actions([TestAction::assert_eq(scenario, js_string!("foobar"))]); run_test_actions([TestAction::assert_eq(scenario, "foobar")]);
} }
#[test] #[test]
@ -228,7 +228,7 @@ fn try_break_labels() {
} }
"#; "#;
run_test_actions([TestAction::assert_eq(scenario, js_string!("finally! :)"))]); run_test_actions([TestAction::assert_eq(scenario, "finally! :)")]);
} }
#[test] #[test]
@ -268,10 +268,10 @@ fn break_nested_labels_loops_and_try() {
run_test_actions([ run_test_actions([
TestAction::run(scenario), TestAction::run(scenario),
TestAction::assert_eq("nestedLabels(true)", js_string!("foobar broke-foo")), TestAction::assert_eq("nestedLabels(true)", "foobar broke-foo"),
TestAction::assert_eq( TestAction::assert_eq(
"nestedLabels(false)", "nestedLabels(false)",
js_string!("foobar broke-bar broke-spacer broke-foo"), "foobar broke-bar broke-spacer broke-foo",
), ),
]); ]);
} }
@ -376,7 +376,7 @@ fn break_environment_gauntlet() {
} }
"#; "#;
run_test_actions([TestAction::assert_eq(scenario, js_string!("5601try_block"))]); run_test_actions([TestAction::assert_eq(scenario, "5601try_block")]);
} }
#[test] #[test]
@ -707,7 +707,7 @@ fn for_loop_break_label() {
} }
str str
"#}, "#},
js_string!("01"), "01",
)]); )]);
} }
@ -822,7 +822,7 @@ fn for_in_break_label() {
} }
str str
"#}, "#},
js_string!("0"), "0",
)]); )]);
} }
@ -843,6 +843,6 @@ fn for_in_continue_label() {
} }
str str
"#}, "#},
js_string!("00"), "00",
)]); )]);
} }

22
boa_engine/src/tests/control_flow/mod.rs

@ -1,7 +1,7 @@
use indoc::indoc; use indoc::indoc;
mod loops; mod loops;
use crate::{js_string, run_test_actions, JsNativeErrorKind, TestAction}; use crate::{run_test_actions, JsNativeErrorKind, TestAction};
#[test] #[test]
fn test_invalid_break() { fn test_invalid_break() {
@ -381,7 +381,7 @@ fn string_switch() {
a; a;
"#}, "#},
js_string!("world"), "world",
)]); )]);
} }
@ -418,13 +418,13 @@ fn bigger_switch_example() {
return b; return b;
} }
"#}), "#}),
TestAction::assert_eq("f(0)", js_string!("Mon")), TestAction::assert_eq("f(0)", "Mon"),
TestAction::assert_eq("f(1)", js_string!("Tue")), TestAction::assert_eq("f(1)", "Tue"),
TestAction::assert_eq("f(2)", js_string!("Wed")), TestAction::assert_eq("f(2)", "Wed"),
TestAction::assert_eq("f(3)", js_string!("Thurs")), TestAction::assert_eq("f(3)", "Thurs"),
TestAction::assert_eq("f(4)", js_string!("Fri")), TestAction::assert_eq("f(4)", "Fri"),
TestAction::assert_eq("f(5)", js_string!("Sat")), TestAction::assert_eq("f(5)", "Sat"),
TestAction::assert_eq("f(6)", js_string!("Sun")), TestAction::assert_eq("f(6)", "Sun"),
]); ]);
} }
@ -440,7 +440,7 @@ fn break_labelled_if_statement() {
} }
result result
"#}, "#},
js_string!("foo"), "foo",
)]); )]);
} }
@ -458,6 +458,6 @@ fn break_labelled_try_statement() {
} }
result result
"#}, "#},
js_string!("foo"), "foo",
)]); )]);
} }

6
boa_engine/src/tests/env.rs

@ -1,6 +1,6 @@
use indoc::indoc; use indoc::indoc;
use crate::{js_string, run_test_actions, JsNativeErrorKind, TestAction}; use crate::{run_test_actions, JsNativeErrorKind, TestAction};
#[test] #[test]
// https://github.com/boa-dev/boa/issues/2317 // https://github.com/boa-dev/boa/issues/2317
@ -15,7 +15,7 @@ fn fun_block_eval_2317() {
return y + x; return y + x;
})("arg"); })("arg");
"#}, "#},
js_string!("arginner"), "arginner",
), ),
TestAction::assert_eq( TestAction::assert_eq(
indoc! {r#" indoc! {r#"
@ -26,7 +26,7 @@ fn fun_block_eval_2317() {
return y + x; return y + x;
})(); })();
"#}, "#},
js_string!("defaultinner"), "defaultinner",
), ),
]); ]);
} }

12
boa_engine/src/tests/function.rs

@ -1,4 +1,4 @@
use crate::{js_string, run_test_actions, JsNativeErrorKind, JsValue, TestAction}; use crate::{run_test_actions, JsNativeErrorKind, JsValue, TestAction};
use indoc::indoc; use indoc::indoc;
#[test] #[test]
@ -24,7 +24,7 @@ fn property_accessor_member_expression_dot_notation_on_function() {
function asd () {}; function asd () {};
asd.name; asd.name;
"#}, "#},
js_string!("asd"), "asd",
)]); )]);
} }
@ -35,7 +35,7 @@ fn property_accessor_member_expression_bracket_notation_on_function() {
function asd () {}; function asd () {};
asd['name']; asd['name'];
"#}, "#},
js_string!("asd"), "asd",
)]); )]);
} }
@ -62,7 +62,7 @@ fn early_return() {
} }
outer_fnct() outer_fnct()
"#}, "#},
js_string!("outer"), "outer",
), ),
]); ]);
} }
@ -78,8 +78,8 @@ fn should_set_this_value() {
var bar = new Foo(); var bar = new Foo();
"#}), "#}),
TestAction::assert_eq("bar.a", js_string!("a")), TestAction::assert_eq("bar.a", "a"),
TestAction::assert_eq("bar.b", js_string!("b")), TestAction::assert_eq("bar.b", "b"),
]); ]);
} }

6
boa_engine/src/tests/mod.rs

@ -8,7 +8,7 @@ mod operators;
mod promise; mod promise;
mod spread; mod spread;
use crate::{js_string, run_test_actions, JsNativeErrorKind, JsValue, TestAction}; use crate::{run_test_actions, JsNativeErrorKind, JsValue, TestAction};
#[test] #[test]
fn length_correct_value_on_string_literal() { fn length_correct_value_on_string_literal() {
@ -355,7 +355,7 @@ fn multiline_str_concat() {
'world'; 'world';
a a
"#}, "#},
js_string!("hello world"), "hello world",
)]); )]);
} }
@ -479,7 +479,7 @@ fn template_literal() {
let a = 10; let a = 10;
`result: ${a} and ${a+10}`; `result: ${a} and ${a+10}`;
"#}, "#},
js_string!("result: 10 and 20"), "result: 10 and 20",
)]); )]);
} }

34
boa_engine/src/tests/operators.rs

@ -1,19 +1,16 @@
use crate::{js_string, run_test_actions, JsNativeErrorKind, JsValue, TestAction}; use crate::{run_test_actions, JsNativeErrorKind, JsValue, TestAction};
use indoc::indoc; use indoc::indoc;
#[test] #[test]
fn property_accessor_member_expression_dot_notation_on_string_literal() { fn property_accessor_member_expression_dot_notation_on_string_literal() {
run_test_actions([TestAction::assert_eq( run_test_actions([TestAction::assert_eq("typeof 'asd'.matchAll", "function")]);
"typeof 'asd'.matchAll",
js_string!("function"),
)]);
} }
#[test] #[test]
fn property_accessor_member_expression_bracket_notation_on_string_literal() { fn property_accessor_member_expression_bracket_notation_on_string_literal() {
run_test_actions([TestAction::assert_eq( run_test_actions([TestAction::assert_eq(
"typeof 'asd'['matchAll']", "typeof 'asd'['matchAll']",
js_string!("function"), "function",
)]); )]);
} }
@ -197,15 +194,15 @@ fn unary_operations_on_this() {
#[test] #[test]
fn typeofs() { fn typeofs() {
run_test_actions([ run_test_actions([
TestAction::assert_eq("typeof String()", js_string!("string")), TestAction::assert_eq("typeof String()", "string"),
TestAction::assert_eq("typeof 5", js_string!("number")), TestAction::assert_eq("typeof 5", "number"),
TestAction::assert_eq("typeof 0.5", js_string!("number")), TestAction::assert_eq("typeof 0.5", "number"),
TestAction::assert_eq("typeof undefined", js_string!("undefined")), TestAction::assert_eq("typeof undefined", "undefined"),
TestAction::assert_eq("typeof true", js_string!("boolean")), TestAction::assert_eq("typeof true", "boolean"),
TestAction::assert_eq("typeof null", js_string!("object")), TestAction::assert_eq("typeof null", "object"),
TestAction::assert_eq("typeof {}", js_string!("object")), TestAction::assert_eq("typeof {}", "object"),
TestAction::assert_eq("typeof Symbol()", js_string!("symbol")), TestAction::assert_eq("typeof Symbol()", "symbol"),
TestAction::assert_eq("typeof function(){}", js_string!("function")), TestAction::assert_eq("typeof function(){}", "function"),
]); ]);
} }
@ -248,7 +245,7 @@ fn unary_void() {
const b = void test() + ''; const b = void test() + '';
a + b a + b
"#}, "#},
js_string!("42undefined"), "42undefined",
), ),
]); ]);
} }
@ -494,10 +491,7 @@ fn logical_assignment() {
#[test] #[test]
fn conditional_op() { fn conditional_op() {
run_test_actions([TestAction::assert_eq( run_test_actions([TestAction::assert_eq("1 === 2 ? 'a' : 'b'", "b")]);
"1 === 2 ? 'a' : 'b'",
js_string!("b"),
)]);
} }
#[test] #[test]

8
boa_engine/src/tests/spread.rs

@ -1,4 +1,4 @@
use crate::{js_string, run_test_actions, JsNativeErrorKind, JsValue, TestAction}; use crate::{run_test_actions, JsNativeErrorKind, JsValue, TestAction};
use indoc::indoc; use indoc::indoc;
#[test] #[test]
@ -26,7 +26,7 @@ fn spread_with_arguments() {
var result = foo(...a); var result = foo(...a);
"#}), "#}),
TestAction::assert_eq("result[0]", 1), TestAction::assert_eq("result[0]", 1),
TestAction::assert_eq("result[1]", js_string!("test")), TestAction::assert_eq("result[1]", "test"),
TestAction::assert_eq("result[2]", 3), TestAction::assert_eq("result[2]", 3),
TestAction::assert_eq("result[3]", 4), TestAction::assert_eq("result[3]", 4),
]); ]);
@ -131,7 +131,7 @@ fn spread_with_new() {
} }
f('message').m; f('message').m;
"#}, "#},
js_string!("message"), "message",
)]); )]);
} }
@ -147,6 +147,6 @@ fn spread_with_call() {
} }
g('message'); g('message');
"#}, "#},
js_string!("message"), "message",
)]); )]);
} }

8
boa_engine/src/value/conversions/mod.rs

@ -7,6 +7,14 @@ use super::{JsBigInt, JsObject, JsString, JsSymbol, JsValue, Profiler};
mod serde_json; mod serde_json;
pub(super) mod try_from_js; pub(super) mod try_from_js;
impl From<&str> for JsValue {
fn from(value: &str) -> Self {
let _timer = Profiler::global().start_event("From<&str>", "value");
Self::String(JsString::from(value))
}
}
impl From<JsString> for JsValue { impl From<JsString> for JsValue {
fn from(value: JsString) -> Self { fn from(value: JsString) -> Self {
let _timer = Profiler::global().start_event("From<JsString>", "value"); let _timer = Profiler::global().start_event("From<JsString>", "value");

6
boa_engine/src/value/conversions/serde_json.rs

@ -181,7 +181,7 @@ mod tests {
use crate::object::JsArray; use crate::object::JsArray;
use crate::JsValue; use crate::JsValue;
use crate::{js_string, run_test_actions, TestAction}; use crate::{run_test_actions, TestAction};
#[test] #[test]
fn json_conversions() { fn json_conversions() {
@ -209,7 +209,7 @@ mod tests {
let value = JsValue::from_json(&json, ctx).unwrap(); let value = JsValue::from_json(&json, ctx).unwrap();
let obj = value.as_object().unwrap(); let obj = value.as_object().unwrap();
assert_eq!(obj.get("name", ctx).unwrap(), js_string!("John Doe").into()); assert_eq!(obj.get("name", ctx).unwrap(), "John Doe".into());
assert_eq!(obj.get("age", ctx).unwrap(), 43_i32.into()); assert_eq!(obj.get("age", ctx).unwrap(), 43_i32.into());
assert_eq!(obj.get("minor", ctx).unwrap(), false.into()); assert_eq!(obj.get("minor", ctx).unwrap(), false.into());
assert_eq!(obj.get("adult", ctx).unwrap(), true.into()); assert_eq!(obj.get("adult", ctx).unwrap(), true.into());
@ -223,7 +223,7 @@ mod tests {
let phones = phones.as_object().unwrap(); let phones = phones.as_object().unwrap();
let arr = JsArray::from_object(phones.clone()).unwrap(); let arr = JsArray::from_object(phones.clone()).unwrap();
assert_eq!(arr.at(0, ctx).unwrap(), js_string!("+44 1234567").into()); assert_eq!(arr.at(0, ctx).unwrap(), "+44 1234567".into());
assert_eq!(arr.at(1, ctx).unwrap(), JsValue::from(-45_i32)); assert_eq!(arr.at(1, ctx).unwrap(), JsValue::from(-45_i32));
assert!(arr.at(2, ctx).unwrap().is_object()); assert!(arr.at(2, ctx).unwrap().is_object());
assert_eq!(arr.at(3, ctx).unwrap(), true.into()); assert_eq!(arr.at(3, ctx).unwrap(), true.into());

26
boa_engine/src/value/mod.rs

@ -19,7 +19,6 @@ use crate::{
Number, Number,
}, },
error::JsNativeError, error::JsNativeError,
js_string,
object::{JsObject, ObjectData}, object::{JsObject, ObjectData},
property::{PropertyDescriptor, PropertyKey}, property::{PropertyDescriptor, PropertyKey},
symbol::JsSymbol, symbol::JsSymbol,
@ -367,9 +366,9 @@ impl JsValue {
// 1. Assert: preferredType is number. // 1. Assert: preferredType is number.
// 2. Let hint be "number". // 2. Let hint be "number".
let hint = match preferred_type { let hint = match preferred_type {
PreferredType::Default => js_string!("default"), PreferredType::Default => "default",
PreferredType::String => js_string!("string"), PreferredType::String => "string",
PreferredType::Number => js_string!("number"), PreferredType::Number => "number",
} }
.into(); .into();
@ -983,21 +982,22 @@ impl JsValue {
#[must_use] #[must_use]
pub fn js_type_of(&self) -> JsString { pub fn js_type_of(&self) -> JsString {
match *self { match *self {
Self::Rational(_) | Self::Integer(_) => js_string!("number"), Self::Rational(_) | Self::Integer(_) => "number",
Self::String(_) => js_string!("string"), Self::String(_) => "string",
Self::Boolean(_) => js_string!("boolean"), Self::Boolean(_) => "boolean",
Self::Symbol(_) => js_string!("symbol"), Self::Symbol(_) => "symbol",
Self::Null => js_string!("object"), Self::Null => "object",
Self::Undefined => js_string!("undefined"), Self::Undefined => "undefined",
Self::BigInt(_) => js_string!("bigint"), Self::BigInt(_) => "bigint",
Self::Object(ref object) => { Self::Object(ref object) => {
if object.is_callable() { if object.is_callable() {
js_string!("function") "function"
} else { } else {
js_string!("object") "object"
} }
} }
} }
.into()
} }
/// Abstract operation `IsArray ( argument )` /// Abstract operation `IsArray ( argument )`

40
boa_engine/src/value/tests.rs

@ -26,9 +26,9 @@ fn get_set_field() {
run_test_actions([TestAction::assert_context(|ctx| { run_test_actions([TestAction::assert_context(|ctx| {
let obj = &JsObject::with_object_proto(ctx.intrinsics()); let obj = &JsObject::with_object_proto(ctx.intrinsics());
// Create string and convert it to a Value // Create string and convert it to a Value
let s = JsValue::new(js_string!("bar")); let s = JsValue::new("bar");
obj.set(js_string!("foo"), s, false, ctx).unwrap(); obj.set("foo", s, false, ctx).unwrap();
obj.get(js_string!("foo"), ctx).unwrap() == JsValue::new(js_string!("bar")) obj.get("foo", ctx).unwrap() == JsValue::new("bar")
})]); })]);
} }
@ -197,9 +197,9 @@ fn float_display() {
#[test] #[test]
fn string_length_is_not_enumerable() { fn string_length_is_not_enumerable() {
run_test_actions([TestAction::assert_context(|ctx| { run_test_actions([TestAction::assert_context(|ctx| {
let object = JsValue::new(js_string!("foo")).to_object(ctx).unwrap(); let object = JsValue::new("foo").to_object(ctx).unwrap();
let length_desc = object let length_desc = object
.__get_own_property__(&js_string!("length").into(), ctx) .__get_own_property__(&"length".into(), ctx)
.unwrap() .unwrap()
.unwrap(); .unwrap();
!length_desc.expect_enumerable() !length_desc.expect_enumerable()
@ -210,9 +210,9 @@ fn string_length_is_not_enumerable() {
fn string_length_is_in_utf16_codeunits() { fn string_length_is_in_utf16_codeunits() {
run_test_actions([TestAction::assert_context(|ctx| { run_test_actions([TestAction::assert_context(|ctx| {
// 😀 is one Unicode code point, but 2 UTF-16 code units // 😀 is one Unicode code point, but 2 UTF-16 code units
let object = JsValue::new(js_string!("😀")).to_object(ctx).unwrap(); let object = JsValue::new("😀").to_object(ctx).unwrap();
let length_desc = object let length_desc = object
.__get_own_property__(&js_string!("length").into(), ctx) .__get_own_property__(&"length".into(), ctx)
.unwrap() .unwrap()
.unwrap(); .unwrap();
length_desc length_desc
@ -230,17 +230,14 @@ fn add_number_and_number() {
#[test] #[test]
fn add_number_and_string() { fn add_number_and_string() {
run_test_actions([TestAction::assert_eq( run_test_actions([TestAction::assert_eq("1 + \" + 2 = 3\"", "1 + 2 = 3")]);
"1 + \" + 2 = 3\"",
js_string!("1 + 2 = 3"),
)]);
} }
#[test] #[test]
fn add_string_and_string() { fn add_string_and_string() {
run_test_actions([TestAction::assert_eq( run_test_actions([TestAction::assert_eq(
"\"Hello\" + \", world\"", "\"Hello\" + \", world\"",
js_string!("Hello, world"), "Hello, world",
)]); )]);
} }
@ -253,7 +250,7 @@ fn add_number_object_and_number() {
fn add_number_object_and_string_object() { fn add_number_object_and_string_object() {
run_test_actions([TestAction::assert_eq( run_test_actions([TestAction::assert_eq(
"new Number(10) + new String(\"0\")", "new Number(10) + new String(\"0\")",
js_string!("100"), "100",
)]); )]);
} }
@ -436,9 +433,7 @@ fn to_integer_or_infinity() {
IntegerOrInfinity::Integer(11) IntegerOrInfinity::Integer(11)
); );
assert_eq!( assert_eq!(
JsValue::new(js_string!("12")) JsValue::new("12").to_integer_or_infinity(ctx).unwrap(),
.to_integer_or_infinity(ctx)
.unwrap(),
IntegerOrInfinity::Integer(12) IntegerOrInfinity::Integer(12)
); );
assert_eq!( assert_eq!(
@ -456,8 +451,8 @@ fn test_accessors() {
let a = { get b() { return "c" }, set b(value) { arr = arr.concat([value]) }} ; let a = { get b() { return "c" }, set b(value) { arr = arr.concat([value]) }} ;
a.b = "a"; a.b = "a";
"#}), "#}),
TestAction::assert_eq("a.b", js_string!("c")), TestAction::assert_eq("a.b", "c"),
TestAction::assert_eq("arr[0]", js_string!("a")), TestAction::assert_eq("arr[0]", "a"),
]); ]);
} }
@ -678,10 +673,7 @@ fn to_string() {
assert_eq!(&JsValue::undefined().to_string(ctx).unwrap(), "undefined"); assert_eq!(&JsValue::undefined().to_string(ctx).unwrap(), "undefined");
assert_eq!(&JsValue::new(55).to_string(ctx).unwrap(), "55"); assert_eq!(&JsValue::new(55).to_string(ctx).unwrap(), "55");
assert_eq!(&JsValue::new(55.0).to_string(ctx).unwrap(), "55"); assert_eq!(&JsValue::new(55.0).to_string(ctx).unwrap(), "55");
assert_eq!( assert_eq!(&JsValue::new("hello").to_string(ctx).unwrap(), "hello");
&JsValue::new(js_string!("hello")).to_string(ctx).unwrap(),
"hello"
);
})]); })]);
} }
@ -692,7 +684,7 @@ fn to_bigint() {
assert!(JsValue::undefined().to_bigint(ctx).is_err()); assert!(JsValue::undefined().to_bigint(ctx).is_err());
assert!(JsValue::new(55).to_bigint(ctx).is_err()); assert!(JsValue::new(55).to_bigint(ctx).is_err());
assert!(JsValue::new(10.0).to_bigint(ctx).is_err()); assert!(JsValue::new(10.0).to_bigint(ctx).is_err());
assert!(JsValue::new(js_string!("100")).to_bigint(ctx).is_ok()); assert!(JsValue::new("100").to_bigint(ctx).is_ok());
})]); })]);
} }
@ -725,7 +717,7 @@ mod cyclic_conversions {
let a = [b, b]; let a = [b, b];
JSON.stringify(a) JSON.stringify(a)
"#}, "#},
js_string!("[[],[]]"), "[[],[]]",
)]); )]);
} }

26
boa_engine/src/vm/tests.rs

@ -1,4 +1,4 @@
use crate::{js_string, run_test_actions, JsNativeErrorKind, JsValue, TestAction}; use crate::{run_test_actions, JsNativeErrorKind, JsValue, TestAction};
use indoc::indoc; use indoc::indoc;
#[test] #[test]
@ -8,7 +8,7 @@ fn typeof_string() {
const a = "hello"; const a = "hello";
typeof a; typeof a;
"#}, "#},
js_string!("string"), "string",
)]); )]);
} }
@ -19,7 +19,7 @@ fn typeof_number() {
let a = 1234; let a = 1234;
typeof a; typeof a;
"#}, "#},
js_string!("number"), "number",
)]); )]);
} }
@ -50,7 +50,7 @@ fn try_catch_finally_from_init() {
} finally { } finally {
} }
"#}, "#},
js_string!("h"), "h",
)]); )]);
} }
@ -85,7 +85,7 @@ fn use_last_expr_try_block() {
"Bye!" "Bye!"
} }
"#}, "#},
js_string!("Hello!"), "Hello!",
)]); )]);
} }
@ -102,7 +102,7 @@ fn use_last_expr_catch_block() {
"Hello!"; "Hello!";
} }
"#}, "#},
js_string!("Hello!"), "Hello!",
)]); )]);
} }
@ -133,7 +133,7 @@ fn finally_block_binding_env() {
} }
buf buf
"#}, "#},
js_string!("Hey hey people"), "Hey hey people",
)]); )]);
} }
@ -150,7 +150,7 @@ fn run_super_method_in_object() {
Object.setPrototypeOf(obj, proto); Object.setPrototypeOf(obj, proto);
obj.v(); obj.v();
"#}, "#},
js_string!("super"), "super",
)]); )]);
} }
@ -174,7 +174,7 @@ fn get_reference_by_super() {
obj.method(); obj.method();
fromA + fromB fromA + fromB
"#}, "#},
js_string!("ab"), "ab",
)]); )]);
} }
@ -234,7 +234,7 @@ fn order_of_execution_in_assigment_with_comma_expressions() {
(f(1), a)[(f(2), 0)][(f(3), 0)] = (f(4), 123); (f(1), a)[(f(2), 0)][(f(3), 0)] = (f(4), 123);
result result
"#}, "#},
js_string!("1234"), "1234",
)]); )]);
} }
@ -321,7 +321,7 @@ fn arguments_object_constructor_valid_index() {
new F(); new F();
typeof args typeof args
"#}, "#},
js_string!("object"), "object",
)]); )]);
} }
@ -383,7 +383,7 @@ fn super_construction_with_paramater_expression() {
} }
} }
"#}), "#}),
TestAction::assert_eq("new Student().name", js_string!("unknown")), TestAction::assert_eq("new Student().name", "unknown"),
TestAction::assert_eq("new Student('Jack').name", js_string!("Jack")), TestAction::assert_eq("new Student('Jack').name", "Jack"),
]); ]);
} }

2
boa_examples/src/bin/classes.rs

@ -119,7 +119,7 @@ impl Class for Person {
// of `"Im a static property"` and attribute flags `WRITABLE`, `ENUMERABLE` and `PERMANENT`. // of `"Im a static property"` and attribute flags `WRITABLE`, `ENUMERABLE` and `PERMANENT`.
class.static_property( class.static_property(
"staticProperty", "staticProperty",
js_string!("Im a static property"), "Im a static property",
Attribute::WRITABLE | Attribute::ENUMERABLE | Attribute::PERMANENT, Attribute::WRITABLE | Attribute::ENUMERABLE | Attribute::PERMANENT,
); );

10
boa_examples/src/bin/closures.rs

@ -23,7 +23,7 @@ fn main() -> Result<(), JsError> {
// We register a global closure function that has the name 'closure' with length 0. // We register a global closure function that has the name 'closure' with length 0.
context context
.register_global_callable( .register_global_callable(
js_string!("closure"), JsString::from("closure"),
0, 0,
NativeFunction::from_copy_closure(move |_, _, _| { NativeFunction::from_copy_closure(move |_, _, _| {
println!("Called `closure`"); println!("Called `closure`");
@ -54,7 +54,7 @@ fn main() -> Result<(), JsError> {
object.define_property_or_throw( object.define_property_or_throw(
"name", "name",
PropertyDescriptor::builder() PropertyDescriptor::builder()
.value(js_string!("Boa dev")) .value("Boa dev")
.writable(false) .writable(false)
.enumerable(false) .enumerable(false)
.configurable(false), .configurable(false),
@ -121,13 +121,13 @@ fn main() -> Result<(), JsError> {
assert_eq!( assert_eq!(
context.eval(Source::from_bytes("createMessage()"))?, context.eval(Source::from_bytes("createMessage()"))?,
js_string!("message from `Boa dev`: Hello!").into() "message from `Boa dev`: Hello!".into()
); );
// The data mutates between calls // The data mutates between calls
assert_eq!( assert_eq!(
context.eval(Source::from_bytes("createMessage(); createMessage();"))?, context.eval(Source::from_bytes("createMessage(); createMessage();"))?,
js_string!("message from `Boa dev`: Hello! Hello! Hello!").into() "message from `Boa dev`: Hello! Hello! Hello!".into()
); );
// We have moved `Clone` variables into a closure and executed that closure // We have moved `Clone` variables into a closure and executed that closure
@ -144,7 +144,7 @@ fn main() -> Result<(), JsError> {
// We register a global closure that is not `Copy`. // We register a global closure that is not `Copy`.
context context
.register_global_callable( .register_global_callable(
js_string!("enumerate"), JsString::from("enumerate"),
0, 0,
// Note that it is required to use `unsafe` code, since the compiler cannot verify that the // Note that it is required to use `unsafe` code, since the compiler cannot verify that the
// types captured by the closure are not traceable. // types captured by the closure are not traceable.

4
boa_examples/src/bin/futures.rs

@ -10,7 +10,7 @@ use boa_engine::{
js_string, js_string,
native_function::NativeFunction, native_function::NativeFunction,
property::Attribute, property::Attribute,
Context, JsArgs, JsResult, JsValue, Source, Context, JsArgs, JsResult, JsString, JsValue, Source,
}; };
use boa_runtime::Console; use boa_runtime::Console;
use futures_util::{stream::FuturesUnordered, Future}; use futures_util::{stream::FuturesUnordered, Future};
@ -142,7 +142,7 @@ fn add_runtime(context: &mut Context<'_>) {
// Then, bind the defined async function to the ECMAScript function "delay". // Then, bind the defined async function to the ECMAScript function "delay".
context context
.register_global_builtin_callable( .register_global_builtin_callable(
js_string!("delay"), JsString::from("delay"),
1, 1,
NativeFunction::from_async_fn(delay), NativeFunction::from_async_fn(delay),
) )

6
boa_examples/src/bin/host_defined.rs

@ -1,7 +1,7 @@
// This example goes into the details on how to store user defined structs/state that is shared. // This example goes into the details on how to store user defined structs/state that is shared.
use boa_engine::{ use boa_engine::{
js_string, native_function::NativeFunction, Context, JsArgs, JsError, JsNativeError, Source, native_function::NativeFunction, Context, JsArgs, JsError, JsNativeError, JsString, Source,
}; };
use boa_gc::{Finalize, Trace}; use boa_gc::{Finalize, Trace};
@ -81,7 +81,7 @@ fn main() -> Result<(), JsError> {
// //
// The funtion lives in the context's realm and has access to the host-defined field. // The funtion lives in the context's realm and has access to the host-defined field.
context.register_global_builtin_callable( context.register_global_builtin_callable(
js_string!("setRealmValue"), JsString::from("setRealmValue"),
1, 1,
NativeFunction::from_fn_ptr(|_, args, context| { NativeFunction::from_fn_ptr(|_, args, context| {
let value: usize = args.get_or_undefined(0).try_js_into(context)?; let value: usize = args.get_or_undefined(0).try_js_into(context)?;
@ -100,7 +100,7 @@ fn main() -> Result<(), JsError> {
)?; )?;
context.register_global_builtin_callable( context.register_global_builtin_callable(
js_string!("getRealmValue"), JsString::from("getRealmValue"),
0, 0,
NativeFunction::from_fn_ptr(|_, _, context| { NativeFunction::from_fn_ptr(|_, _, context| {
let host_defined = context.realm().host_defined(); let host_defined = context.realm().host_defined();

10
boa_examples/src/bin/jsarray.rs

@ -1,7 +1,6 @@
// This example shows how to manipulate a Javascript array using Rust code. // This example shows how to manipulate a Javascript array using Rust code.
use boa_engine::{ use boa_engine::{
js_string,
native_function::NativeFunction, native_function::NativeFunction,
object::{builtins::JsArray, FunctionObjectBuilder}, object::{builtins::JsArray, FunctionObjectBuilder},
Context, JsResult, JsValue, Context, JsResult, JsValue,
@ -16,16 +15,13 @@ fn main() -> JsResult<()> {
assert!(array.is_empty(context)?); assert!(array.is_empty(context)?);
array.push(js_string!("Hello, world"), context)?; // [ "Hello, world" ] array.push("Hello, world", context)?; // [ "Hello, world" ]
array.push(true, context)?; // [ "Hello, world", true ] array.push(true, context)?; // [ "Hello, world", true ]
assert!(!array.is_empty(context)?); assert!(!array.is_empty(context)?);
assert_eq!(array.pop(context)?, JsValue::new(true)); // [ "Hello, world" ] assert_eq!(array.pop(context)?, JsValue::new(true)); // [ "Hello, world" ]
assert_eq!( assert_eq!(array.pop(context)?, JsValue::new("Hello, world")); // [ ]
array.pop(context)?,
JsValue::new(js_string!("Hello, world"))
); // [ ]
assert_eq!(array.pop(context)?, JsValue::undefined()); // [ ] assert_eq!(array.pop(context)?, JsValue::undefined()); // [ ]
array.push(1, context)?; // [ 1 ] array.push(1, context)?; // [ 1 ]
@ -116,7 +112,7 @@ fn main() -> JsResult<()> {
context context
.global_object() .global_object()
.set(js_string!("myArray"), array, true, context)?; .set("myArray", array, true, context)?;
Ok(()) Ok(())
} }

14
boa_examples/src/bin/jsdate.rs

@ -1,6 +1,4 @@
use boa_engine::{ use boa_engine::{context::HostHooks, object::builtins::JsDate, Context, JsResult, JsValue};
context::HostHooks, js_string, object::builtins::JsDate, Context, JsResult, JsValue,
};
use chrono::{DateTime, FixedOffset, LocalResult, NaiveDateTime, TimeZone}; use chrono::{DateTime, FixedOffset, LocalResult, NaiveDateTime, TimeZone};
struct CustomTimezone; struct CustomTimezone;
@ -66,27 +64,27 @@ fn main() -> JsResult<()> {
assert_eq!( assert_eq!(
date.to_json(context)?, date.to_json(context)?,
JsValue::from(js_string!("2000-10-09T20:12:59.059Z")) JsValue::from("2000-10-09T20:12:59.059Z")
); );
assert_eq!( assert_eq!(
date.to_date_string(context)?, date.to_date_string(context)?,
JsValue::from(js_string!("Mon Oct 09 2000")) JsValue::from("Mon Oct 09 2000")
); );
assert_eq!( assert_eq!(
date.to_iso_string(context)?, date.to_iso_string(context)?,
JsValue::from(js_string!("2000-10-09T20:12:59.059Z")) JsValue::from("2000-10-09T20:12:59.059Z")
); );
assert_eq!( assert_eq!(
date.to_time_string(context)?, date.to_time_string(context)?,
JsValue::from(js_string!("23:12:59 GMT+0300")) JsValue::from("23:12:59 GMT+0300")
); );
assert_eq!( assert_eq!(
date.to_string(context)?, date.to_string(context)?,
JsValue::from(js_string!("Mon Oct 09 2000 23:12:59 GMT+0300")) JsValue::from("Mon Oct 09 2000 23:12:59 GMT+0300")
); );
Ok(()) Ok(())

31
boa_examples/src/bin/jsmap.rs

@ -1,5 +1,4 @@
use boa_engine::{ use boa_engine::{
js_string,
object::{builtins::JsArray, builtins::JsMap}, object::{builtins::JsArray, builtins::JsMap},
Context, JsResult, JsValue, Context, JsResult, JsValue,
}; };
@ -12,9 +11,9 @@ fn main() -> JsResult<()> {
let map = JsMap::new(context); let map = JsMap::new(context);
// Set a key-value for the map. // Set a key-value for the map.
map.set(js_string!("Key-1"), js_string!("Value-1"), context)?; map.set("Key-1", "Value-1", context)?;
let map_check = map.has(js_string!("Key-1"), context)?; let map_check = map.has("Key-1", context)?;
assert_eq!(map_check, true.into()); // true assert_eq!(map_check, true.into()); // true
// Set a second key-value to the same map. // Set a second key-value to the same map.
@ -22,16 +21,13 @@ fn main() -> JsResult<()> {
assert_eq!(map.get_size(context)?, 2.into()); //true assert_eq!(map.get_size(context)?, 2.into()); //true
assert_eq!( assert_eq!(map.get("Key-1", context)?, "Value-1".into());
map.get(js_string!("Key-1"), context)?,
js_string!("Value-1").into()
);
assert_eq!(map.get(2, context)?, 4.into()); assert_eq!(map.get(2, context)?, 4.into());
// Delete an entry with a provided key. // Delete an entry with a provided key.
map.delete(js_string!("Key-1"), context)?; map.delete("Key-1", context)?;
assert_eq!(map.get_size(context)?, 1.into()); assert_eq!(map.get_size(context)?, 1.into());
let deleted_key_one = map.get(js_string!("Key-1"), context)?; let deleted_key_one = map.get("Key-1", context)?;
assert_eq!(deleted_key_one, JsValue::undefined()); assert_eq!(deleted_key_one, JsValue::undefined());
@ -43,14 +39,8 @@ fn main() -> JsResult<()> {
// Create a multidimensional array with key value pairs -> [[first-key, first-value], [second-key, second-value]] // Create a multidimensional array with key value pairs -> [[first-key, first-value], [second-key, second-value]]
let js_array = JsArray::new(context); let js_array = JsArray::new(context);
let vec_one = vec![ let vec_one = vec![JsValue::new("first-key"), JsValue::new("first-value")];
JsValue::new(js_string!("first-key")), let vec_two = vec![JsValue::new("second-key"), JsValue::new("second-value")];
JsValue::new(js_string!("first-value")),
];
let vec_two = vec![
JsValue::new(js_string!("second-key")),
JsValue::new(js_string!("second-value")),
];
js_array.push(JsArray::from_iter(vec_one, context), context)?; js_array.push(JsArray::from_iter(vec_one, context), context)?;
js_array.push(JsArray::from_iter(vec_two, context), context)?; js_array.push(JsArray::from_iter(vec_two, context), context)?;
@ -58,12 +48,9 @@ fn main() -> JsResult<()> {
// Create a map from the JsArray using it's iterable property. // Create a map from the JsArray using it's iterable property.
let iter_map = JsMap::from_js_iterable(&js_array.into(), context)?; let iter_map = JsMap::from_js_iterable(&js_array.into(), context)?;
assert_eq!( assert_eq!(iter_map.get("first-key", context)?, "first-value".into());
iter_map.get(js_string!("first-key"), context)?,
js_string!("first-value").into()
);
iter_map.set(js_string!("third-key"), js_string!("third-value"), context)?; iter_map.set("third-key", "third-value", context)?;
assert_eq!(iter_map.get_size(context)?, JsValue::new(3)); assert_eq!(iter_map.get_size(context)?, JsValue::new(3));

6
boa_examples/src/bin/jsregexp.rs

@ -1,11 +1,11 @@
use boa_engine::{js_string, object::builtins::JsRegExp, Context, JsResult}; use boa_engine::{object::builtins::JsRegExp, Context, JsResult};
fn main() -> JsResult<()> { fn main() -> JsResult<()> {
let context = &mut Context::default(); let context = &mut Context::default();
let regexp = JsRegExp::new(js_string!("foo"), js_string!("gi"), context)?; let regexp = JsRegExp::new("foo", "gi", context)?;
let test_result = regexp.test(js_string!("football"), context)?; let test_result = regexp.test("football", context)?;
assert!(test_result); assert!(test_result);
let flags = regexp.flags(context)?; let flags = regexp.flags(context)?;

20
boa_examples/src/bin/jsset.rs

@ -1,6 +1,6 @@
// This example shows how to manipulate a Javascript Set using Rust code. // This example shows how to manipulate a Javascript Set using Rust code.
#![allow(clippy::bool_assert_comparison)] #![allow(clippy::bool_assert_comparison)]
use boa_engine::{js_string, object::builtins::JsSet, Context, JsError, JsValue}; use boa_engine::{object::builtins::JsSet, Context, JsError, JsValue};
fn main() -> Result<(), JsError> { fn main() -> Result<(), JsError> {
// New `Context` for a new Javascript executor. // New `Context` for a new Javascript executor.
@ -17,21 +17,21 @@ fn main() -> Result<(), JsError> {
set.clear(context)?; set.clear(context)?;
assert_eq!(set.size()?, 0); assert_eq!(set.size()?, 0);
set.add(js_string!("one"), context)?; set.add("one", context)?;
set.add(js_string!("two"), context)?; set.add("two", context)?;
set.add(js_string!("three"), context)?; set.add("three", context)?;
assert!(set.has(js_string!("one"), context)?); assert!(set.has("one", context)?);
assert_eq!(set.has(js_string!("One"), context)?, false); assert_eq!(set.has("One", context)?, false);
set.delete(js_string!("two"), context)?; set.delete("two", context)?;
assert_eq!(set.has(js_string!("two"), context)?, false); assert_eq!(set.has("two", context)?, false);
set.clear(context)?; set.clear(context)?;
assert_eq!(set.has(js_string!("one"), context)?, false); assert_eq!(set.has("one", context)?, false);
assert_eq!(set.has(js_string!("three"), context)?, false); assert_eq!(set.has("three", context)?, false);
assert_eq!(set.size()?, 0); assert_eq!(set.size()?, 0);
// Add a slice into a set; // Add a slice into a set;

3
boa_examples/src/bin/jstypedarray.rs

@ -1,7 +1,6 @@
// This example shows how to manipulate a Javascript array using Rust code. // This example shows how to manipulate a Javascript array using Rust code.
use boa_engine::{ use boa_engine::{
js_string,
native_function::NativeFunction, native_function::NativeFunction,
object::{builtins::JsUint8Array, FunctionObjectBuilder}, object::{builtins::JsUint8Array, FunctionObjectBuilder},
property::Attribute, property::Attribute,
@ -43,7 +42,7 @@ fn main() -> JsResult<()> {
context context
.register_global_property( .register_global_property(
js_string!("myUint8Array"), "myUint8Array",
array, array,
Attribute::WRITABLE | Attribute::ENUMERABLE | Attribute::CONFIGURABLE, Attribute::WRITABLE | Attribute::ENUMERABLE | Attribute::CONFIGURABLE,
) )

23
boa_examples/src/bin/modulehandler.rs

@ -28,26 +28,13 @@ fn main() -> Result<(), Box<dyn Error>> {
add_runtime(&mut ctx); add_runtime(&mut ctx);
// Adding custom implementation that mimics 'require' // Adding custom implementation that mimics 'require'
ctx.register_global_callable( ctx.register_global_callable("require".into(), 0, NativeFunction::from_fn_ptr(require))?;
js_string!("require"),
0,
NativeFunction::from_fn_ptr(require),
)?;
// Adding custom object that mimics 'module.exports' // Adding custom object that mimics 'module.exports'
let moduleobj = JsObject::default(); let moduleobj = JsObject::default();
moduleobj.set( moduleobj.set("exports", JsValue::from(" "), false, &mut ctx)?;
js_string!("exports"),
JsValue::from(js_string!(" ")),
false,
&mut ctx,
)?;
ctx.register_global_property( ctx.register_global_property("module", JsValue::from(moduleobj), Attribute::default())?;
js_string!("module"),
JsValue::from(moduleobj),
Attribute::default(),
)?;
// Instantiating the engine with the execution context // Instantiating the engine with the execution context
// Loading, parsing and executing the JS code from the source file // Loading, parsing and executing the JS code from the source file
@ -72,9 +59,9 @@ fn require(_: &JsValue, args: &[JsValue], ctx: &mut Context<'_>) -> JsResult<JsV
// Access module.exports and return as ResultValue // Access module.exports and return as ResultValue
let global_obj = ctx.global_object(); let global_obj = ctx.global_object();
let module = global_obj.get(js_string!("module"), ctx)?; let module = global_obj.get("module", ctx)?;
module module
.as_object() .as_object()
.ok_or_else(|| JsNativeError::typ().with_message("`exports` property was not an object"))? .ok_or_else(|| JsNativeError::typ().with_message("`exports` property was not an object"))?
.get(js_string!("exports"), ctx) .get("exports", ctx)
} }

6
boa_runtime/src/console/mod.rs

@ -220,14 +220,14 @@ impl Console {
if !assertion { if !assertion {
let mut args: Vec<JsValue> = args.iter().skip(1).cloned().collect(); let mut args: Vec<JsValue> = args.iter().skip(1).cloned().collect();
let message = js_string!("Assertion failed"); let message = "Assertion failed";
if args.is_empty() { if args.is_empty() {
args.push(JsValue::new(message)); args.push(JsValue::new(message));
} else if !args[0].is_string() { } else if !args[0].is_string() {
args.insert(0, JsValue::new(message)); args.insert(0, JsValue::new(message));
} else { } else {
let value: Vec<u16> = args[0].display().to_string().encode_utf16().collect(); let value = args[0].display().to_string();
let concat = js_string!(&message, ": ", &value[..]); let concat = js_string!(message, ": ", value.as_str());
args[0] = JsValue::new(concat); args[0] = JsValue::new(concat);
} }

23
boa_runtime/src/console/tests.rs

@ -21,7 +21,7 @@ fn formatter_empty_format_string_is_empty_string() {
fn formatter_format_without_args_renders_verbatim() { fn formatter_format_without_args_renders_verbatim() {
run_test_actions([TestAction::inspect_context(|ctx| { run_test_actions([TestAction::inspect_context(|ctx| {
assert_eq!( assert_eq!(
formatter(&[JsValue::new(js_string!("%d %s %% %f"))], ctx).unwrap(), formatter(&[JsValue::new("%d %s %% %f")], ctx).unwrap(),
"%d %s %% %f" "%d %s %% %f"
); );
})]); })]);
@ -33,9 +33,9 @@ fn formatter_empty_format_string_concatenates_rest_of_args() {
assert_eq!( assert_eq!(
formatter( formatter(
&[ &[
JsValue::new(js_string!("")), JsValue::new(""),
JsValue::new(js_string!("to powinno zostać")), JsValue::new("to powinno zostać"),
JsValue::new(js_string!("połączone")), JsValue::new("połączone"),
], ],
ctx ctx
) )
@ -51,10 +51,10 @@ fn formatter_utf_8_checks() {
assert_eq!( assert_eq!(
formatter( formatter(
&[ &[
JsValue::new(js_string!("Są takie chwile %dą %są tu%sów %привет%ź")), JsValue::new("Są takie chwile %dą %są tu%sów %привет%ź"),
JsValue::new(123), JsValue::new(123),
JsValue::new(1.23), JsValue::new(1.23),
JsValue::new(js_string!("ł")), JsValue::new("ł"),
], ],
ctx ctx
) )
@ -68,14 +68,7 @@ fn formatter_utf_8_checks() {
fn formatter_trailing_format_leader_renders() { fn formatter_trailing_format_leader_renders() {
run_test_actions([TestAction::inspect_context(|ctx| { run_test_actions([TestAction::inspect_context(|ctx| {
assert_eq!( assert_eq!(
formatter( formatter(&[JsValue::new("%%%%%"), JsValue::new("|")], ctx).unwrap(),
&[
JsValue::new(js_string!("%%%%%")),
JsValue::new(js_string!("|"))
],
ctx
)
.unwrap(),
"%%% |" "%%% |"
); );
})]); })]);
@ -86,7 +79,7 @@ fn formatter_trailing_format_leader_renders() {
fn formatter_float_format_works() { fn formatter_float_format_works() {
run_test_actions([TestAction::inspect_context(|ctx| { run_test_actions([TestAction::inspect_context(|ctx| {
assert_eq!( assert_eq!(
formatter(&[JsValue::new(js_string!("%f")), JsValue::new(3.1415)], ctx).unwrap(), formatter(&[JsValue::new("%f"), JsValue::new(3.1415)], ctx).unwrap(),
"3.141500" "3.141500"
); );
})]); })]);

6
boa_tester/src/exec/mod.rs

@ -666,10 +666,10 @@ fn is_error_type(error: &JsError, target_type: ErrorType, context: &mut Context<
.as_opaque() .as_opaque()
.expect("try_native cannot fail if e is not opaque") .expect("try_native cannot fail if e is not opaque")
.as_object() .as_object()
.and_then(|o| o.get(js_string!("constructor"), context).ok()) .and_then(|o| o.get("constructor", context).ok())
.as_ref() .as_ref()
.and_then(JsValue::as_object) .and_then(JsValue::as_object)
.and_then(|o| o.get(js_string!("name"), context).ok()) .and_then(|o| o.get("name", context).ok())
.as_ref() .as_ref()
.and_then(JsValue::as_string) .and_then(JsValue::as_string)
.map(|s| s == target_type.as_str()) .map(|s| s == target_type.as_str())
@ -713,7 +713,7 @@ fn register_print_fn(context: &mut Context<'_>, async_result: AsyncResult) {
context context
.register_global_property( .register_global_property(
js_string!("print"), "print",
js_function, js_function,
Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE,
) )

Loading…
Cancel
Save