Skip to content

Commit d65ea9d

Browse files
committed
refactor(tests): share object super oracle protocol
1 parent 86a38cc commit d65ea9d

5 files changed

Lines changed: 133 additions & 131 deletions

File tree

tests/oracle/object/oracle_object_super.rs

Lines changed: 8 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
use std::ffi::OsStr;
2-
use std::process::Command;
3-
41
use quickjs_oxide::{Runtime, RuntimeError, Value};
52

63
struct Case {
@@ -439,7 +436,14 @@ fn object_super_semantics_match_pinned_quickjs() {
439436

440437
let quickjs = CASES
441438
.iter()
442-
.map(|case| oracle_observation(&oracle, case))
439+
.map(|case| {
440+
super::quickjs_object_super_oracle::observe_completion_name_only(
441+
&oracle,
442+
case.source,
443+
case.group,
444+
case.description,
445+
)
446+
})
443447
.collect::<Vec<_>>();
444448
for (case, observation) in CASES.iter().zip(&quickjs) {
445449
assert_eq!(
@@ -526,45 +530,6 @@ fn error_name(
526530
value.to_utf8_lossy()
527531
}
528532

529-
fn oracle_observation(oracle: &OsStr, case: &Case) -> String {
530-
let wrapper = r#"
531-
try {
532-
var value = std.evalScript(scriptArgs[0]);
533-
print('return|' + typeof value + '|' + String(value));
534-
} catch (error) {
535-
if (error !== null && typeof error === 'object')
536-
print('throw|object|' + error.name);
537-
else
538-
print('throw|' + typeof error + '|' + String(error));
539-
}
540-
"#;
541-
let output = Command::new(oracle)
542-
.args(["--std", "-e", wrapper, case.source])
543-
.output()
544-
.unwrap_or_else(|error| {
545-
panic!(
546-
"could not run QuickJS for {} / {}: {error}",
547-
case.group, case.description,
548-
)
549-
});
550-
assert!(
551-
output.status.success(),
552-
"QuickJS observer failed for {} / {}: {}",
553-
case.group,
554-
case.description,
555-
String::from_utf8_lossy(&output.stderr),
556-
);
557-
String::from_utf8(output.stdout)
558-
.unwrap_or_else(|error| {
559-
panic!(
560-
"QuickJS output was not UTF-8 for {} / {}: {error}",
561-
case.group, case.description,
562-
)
563-
})
564-
.trim_end()
565-
.to_owned()
566-
}
567-
568533
fn value_type(runtime: &Runtime, value: &Value) -> &'static str {
569534
match value {
570535
Value::Undefined => "undefined",

tests/oracle/object/oracle_object_super_arrow.rs

Lines changed: 12 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
use std::ffi::OsStr;
2-
use std::process::Command;
3-
41
use quickjs_oxide::{Runtime, RuntimeError, Value};
52

63
struct Case {
@@ -267,7 +264,12 @@ fn pinned_quickjs_object_super_arrow_semantics_match_expectations() {
267264

268265
for case in CASES {
269266
assert_eq!(
270-
oracle_observation(&oracle, case),
267+
super::quickjs_object_super_oracle::observe_completion_name_only(
268+
&oracle,
269+
case.source,
270+
case.group,
271+
case.description,
272+
),
271273
case.expected,
272274
"pinned QuickJS object-super-arrow vector drifted for {} / {}: {:?}",
273275
case.group,
@@ -285,7 +287,12 @@ fn object_super_arrow_semantics_match_pinned_quickjs() {
285287
};
286288

287289
for case in CASES {
288-
let quickjs = oracle_observation(&oracle, case);
290+
let quickjs = super::quickjs_object_super_oracle::observe_completion_name_only(
291+
&oracle,
292+
case.source,
293+
case.group,
294+
case.description,
295+
);
289296
assert_eq!(
290297
rust_observation(case),
291298
quickjs,
@@ -363,45 +370,6 @@ fn error_name(
363370
value.to_utf8_lossy()
364371
}
365372

366-
fn oracle_observation(oracle: &OsStr, case: &Case) -> String {
367-
let wrapper = r#"
368-
try {
369-
var value = std.evalScript(scriptArgs[0]);
370-
print('return|' + typeof value + '|' + String(value));
371-
} catch (error) {
372-
if (error !== null && typeof error === 'object')
373-
print('throw|object|' + error.name);
374-
else
375-
print('throw|' + typeof error + '|' + String(error));
376-
}
377-
"#;
378-
let output = Command::new(oracle)
379-
.args(["--std", "-e", wrapper, case.source])
380-
.output()
381-
.unwrap_or_else(|error| {
382-
panic!(
383-
"could not run QuickJS for {} / {}: {error}",
384-
case.group, case.description,
385-
)
386-
});
387-
assert!(
388-
output.status.success(),
389-
"QuickJS observer failed for {} / {}: {}",
390-
case.group,
391-
case.description,
392-
String::from_utf8_lossy(&output.stderr),
393-
);
394-
String::from_utf8(output.stdout)
395-
.unwrap_or_else(|error| {
396-
panic!(
397-
"QuickJS output was not UTF-8 for {} / {}: {error}",
398-
case.group, case.description,
399-
)
400-
})
401-
.trim_end()
402-
.to_owned()
403-
}
404-
405373
fn value_type(runtime: &Runtime, value: &Value) -> &'static str {
406374
match value {
407375
Value::Undefined => "undefined",

tests/oracle/object/oracle_object_super_eval.rs

Lines changed: 12 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
use std::ffi::OsStr;
2-
use std::process::Command;
3-
41
use quickjs_oxide::{Runtime, RuntimeError, Value};
52

63
struct Case {
@@ -445,7 +442,12 @@ fn pinned_quickjs_object_super_eval_semantics_match_expectations() {
445442

446443
for case in CASES {
447444
assert_eq!(
448-
oracle_observation(&oracle, case),
445+
super::quickjs_object_super_oracle::observe_completion_name_only(
446+
&oracle,
447+
case.source,
448+
case.group,
449+
case.description,
450+
),
449451
case.expected,
450452
"pinned QuickJS object-super-eval vector drifted for {} / {}: {:?}",
451453
case.group,
@@ -463,7 +465,12 @@ fn object_super_eval_semantics_match_pinned_quickjs() {
463465
};
464466

465467
for case in CASES {
466-
let quickjs = oracle_observation(&oracle, case);
468+
let quickjs = super::quickjs_object_super_oracle::observe_completion_name_only(
469+
&oracle,
470+
case.source,
471+
case.group,
472+
case.description,
473+
);
467474
assert_eq!(
468475
rust_observation(case),
469476
quickjs,
@@ -541,45 +548,6 @@ fn error_name(
541548
value.to_utf8_lossy()
542549
}
543550

544-
fn oracle_observation(oracle: &OsStr, case: &Case) -> String {
545-
let wrapper = r#"
546-
try {
547-
var value = std.evalScript(scriptArgs[0]);
548-
print('return|' + typeof value + '|' + String(value));
549-
} catch (error) {
550-
if (error !== null && typeof error === 'object')
551-
print('throw|object|' + error.name);
552-
else
553-
print('throw|' + typeof error + '|' + String(error));
554-
}
555-
"#;
556-
let output = Command::new(oracle)
557-
.args(["--std", "-e", wrapper, case.source])
558-
.output()
559-
.unwrap_or_else(|error| {
560-
panic!(
561-
"could not run QuickJS for {} / {}: {error}",
562-
case.group, case.description,
563-
)
564-
});
565-
assert!(
566-
output.status.success(),
567-
"QuickJS observer failed for {} / {}: {}",
568-
case.group,
569-
case.description,
570-
String::from_utf8_lossy(&output.stderr),
571-
);
572-
String::from_utf8(output.stdout)
573-
.unwrap_or_else(|error| {
574-
panic!(
575-
"QuickJS output was not UTF-8 for {} / {}: {error}",
576-
case.group, case.description,
577-
)
578-
})
579-
.trim_end()
580-
.to_owned()
581-
}
582-
583551
fn value_type(runtime: &Runtime, value: &Value) -> &'static str {
584552
match value {
585553
Value::Undefined => "undefined",

tests/oracle_object_semantics.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#[path = "support/quickjs_object_pattern_oracle.rs"]
55
mod quickjs_object_pattern_oracle;
6+
#[path = "support/quickjs_object_super_oracle.rs"]
7+
mod quickjs_object_super_oracle;
68
#[path = "support/quickjs_oracle.rs"]
79
mod quickjs_oracle;
810

@@ -56,6 +58,66 @@ mod quickjs_object_pattern_oracle_contract {
5658
}
5759
}
5860

61+
#[cfg(test)]
62+
mod quickjs_object_super_oracle_contract {
63+
use super::quickjs_object_super_oracle::observe_completion_name_only;
64+
65+
fn oracle() -> Option<std::ffi::OsString> {
66+
let oracle = std::env::var_os("QJS_ORACLE");
67+
if oracle.is_none() {
68+
eprintln!(
69+
"SKIP object-super oracle helper regressions: set QJS_ORACLE to upstream qjs"
70+
);
71+
}
72+
oracle
73+
}
74+
75+
#[test]
76+
fn preserves_argv_source_and_completion_whitespace() {
77+
let Some(oracle) = oracle() else {
78+
return;
79+
};
80+
assert_eq!(
81+
observe_completion_name_only(&oracle, "-1", "contract", "leading hyphen source"),
82+
"return|number|-1",
83+
);
84+
assert_eq!(
85+
observe_completion_name_only(
86+
&oracle,
87+
"'tail \\n\\t\\r\\u00a0'",
88+
"contract",
89+
"trailing whitespace",
90+
),
91+
"return|string|tail \n\t\r\u{00a0}",
92+
);
93+
}
94+
95+
#[test]
96+
fn preserves_name_only_object_and_primitive_throw_protocol() {
97+
let Some(oracle) = oracle() else {
98+
return;
99+
};
100+
assert_eq!(
101+
observe_completion_name_only(
102+
&oracle,
103+
"throw new TypeError('message must stay omitted')",
104+
"contract",
105+
"object throw",
106+
),
107+
"throw|object|TypeError",
108+
);
109+
assert_eq!(
110+
observe_completion_name_only(
111+
&oracle,
112+
"throw 'tail \\n\\t\\r\\u00a0'",
113+
"contract",
114+
"primitive throw",
115+
),
116+
"throw|string|tail \n\t\r\u{00a0}",
117+
);
118+
}
119+
}
120+
59121
#[path = "oracle/object/oracle_object_accessors.rs"]
60122
mod oracle_object_accessors;
61123
#[path = "oracle/object/oracle_object_assign.rs"]
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use std::ffi::OsStr;
2+
use std::process::Command;
3+
4+
const NAME_ONLY_COMPLETION_OBSERVER: &str = r#"
5+
if(os.platform==='win32')os.ttySetRaw(1);
6+
try {
7+
var value=std.evalScript(scriptArgs[0]);
8+
std.out.puts('return|'+typeof value+'|'+String(value));
9+
} catch(error) {
10+
if(error!==null&&typeof error==='object')
11+
std.out.puts('throw|object|'+error.name);
12+
else
13+
std.out.puts('throw|'+typeof error+'|'+String(error));
14+
}
15+
"#;
16+
17+
pub(super) fn observe_completion_name_only(
18+
oracle: &OsStr,
19+
source: &str,
20+
group: &str,
21+
description: &str,
22+
) -> String {
23+
// Source stays in scriptArgs[0] because these cases observe that host
24+
// contract. `--` keeps leading-hyphen source out of qjs option parsing.
25+
let output = Command::new(oracle)
26+
.args(["--std", "-e", NAME_ONLY_COMPLETION_OBSERVER, "--", source])
27+
.output()
28+
.unwrap_or_else(|error| {
29+
panic!("could not run QuickJS for {group} / {description}: {error}")
30+
});
31+
assert!(
32+
output.status.success(),
33+
"QuickJS observer failed for {group} / {description}: {}",
34+
String::from_utf8_lossy(&output.stderr),
35+
);
36+
String::from_utf8(output.stdout).unwrap_or_else(|error| {
37+
panic!("QuickJS output was not UTF-8 for {group} / {description}: {error}")
38+
})
39+
}

0 commit comments

Comments
 (0)