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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions integration-tests/tests/namespace_members.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use runtime::Runtime;

fn eval(rt: &mut Runtime, expr: &str) -> String {
rt.eval_script_to_string(expr)
.unwrap_or_else(|| "<exception>".to_string())
}

#[test]
fn resolved_members_are_cached() {
let mut rt = Runtime::new(".");
// A miss here means every access builds a new constructor (and a new V8 template).
assert_eq!(eval(&mut rt, "Windows.Foundation.Uri === Windows.Foundation.Uri"), "true");
assert_eq!(eval(&mut rt, "Windows.UI.Xaml === Windows.UI.Xaml"), "true");
assert_eq!(eval(&mut rt, "'Uri' in Windows.Foundation"), "true");
assert_eq!(eval(&mut rt, "Object.keys(Windows.Foundation).length"), "0");
assert_eq!(eval(&mut rt, "Windows.UI.Xaml.Visibility.Collapsed"), "1");
assert_eq!(eval(&mut rt, "new Windows.Foundation.Uri('http://x.y/').Host"), "x.y");
}

#[test]
fn resolved_members_are_read_only() {
let mut rt = Runtime::new(".");
assert_eq!(
eval(&mut rt, "Windows.Foundation.Uri; Windows.Foundation.Uri = 5; typeof Windows.Foundation.Uri"),
"function"
);
assert_eq!(
eval(
&mut rt,
"(function () { 'use strict'; try { Windows.Foundation.Uri = 5; return false } catch (e) { return e instanceof TypeError } })()"
),
"true"
);
assert_eq!(eval(&mut rt, "Windows.Foundation.myShim = 42; Windows.Foundation.myShim"), "42");
}
96 changes: 96 additions & 0 deletions integration-tests/tests/struct_values.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
use runtime::Runtime;

fn eval(rt: &mut Runtime, expr: &str) -> String {
rt.eval_script_to_string(expr)
.unwrap_or_else(|| "<exception>".to_string())
}

#[test]
fn returned_struct_is_plain_object() {
let mut rt = Runtime::new(".");
rt.run_script(
"globalThis.c = Windows.UI.ColorHelper.FromArgb(255, 1, 2, 3);",
"setup.js",
);
assert_eq!(eval(&mut rt, "JSON.stringify(c)"), r#"{"A":255,"R":1,"G":2,"B":3}"#);
assert_eq!(eval(&mut rt, "JSON.stringify({ ...c })"), r#"{"A":255,"R":1,"G":2,"B":3}"#);
assert_eq!(eval(&mut rt, "Object.keys(c).join()"), "A,R,G,B");
assert_eq!(eval(&mut rt, "String(c)"), "[object Windows.UI.Color]");
assert_eq!(eval(&mut rt, "c instanceof Windows.UI.Color"), "true");
assert_eq!(eval(&mut rt, "c.hasOwnProperty('R') && !('zzz' in c)"), "true");
assert_eq!(eval(&mut rt, "c.foo = 5; c.foo"), "5");
assert_eq!(
eval(&mut rt, "Object.getPrototypeOf(c) === Object.getPrototypeOf(Windows.UI.Colors.Red)"),
"true"
);
}

#[test]
fn constructor_builds_independent_values() {
let mut rt = Runtime::new(".");
let v = eval(
&mut rt,
"const a = new Windows.Foundation.Rect({ X: 1, Y: 2, Width: 3, Height: 4 });
const b = new Windows.Foundation.Rect(5, 6, 7, 8);
JSON.stringify([a, b, a instanceof Windows.Foundation.Rect])",
);
assert_eq!(
v,
r#"[{"X":1,"Y":2,"Width":3,"Height":4},{"X":5,"Y":6,"Width":7,"Height":8},true]"#
);
}

#[test]
fn constructor_zero_fills_and_validates() {
let mut rt = Runtime::new(".");
assert_eq!(
eval(&mut rt, "JSON.stringify(new Windows.Foundation.Rect())"),
r#"{"X":0,"Y":0,"Width":0,"Height":0}"#
);
assert_eq!(
eval(&mut rt, "JSON.stringify(new Windows.Foundation.Rect({ X: 1 }))"),
r#"{"X":1,"Y":0,"Width":0,"Height":0}"#
);
assert_eq!(
eval(
&mut rt,
"try { new Windows.Foundation.Rect({ X: 'a' }); 'no' } catch (e) { e instanceof TypeError }"
),
"true"
);
// Integer fields hold what native will receive.
assert_eq!(eval(&mut rt, "new Windows.UI.Color({ R: 1.7 }).R"), "1");
}

#[test]
fn nested_struct_fields_are_read() {
let mut rt = Runtime::new(".");
let v = eval(
&mut rt,
"(() => { try {
const d = Windows.UI.Xaml.DurationHelper.FromTimeSpan({ Duration: 10000000 });
return JSON.stringify(d);
} catch (e) { return 'skip'; } })()",
);
if v != "skip" {
assert_eq!(v, r#"{"TimeSpan":{"Duration":10000000},"Type":1}"#);
}
}

#[test]
fn struct_values_round_trip_through_native() {
let mut rt = Runtime::new(".");
let v = eval(
&mut rt,
"(() => {
const r = new Windows.Media.Core.TimedTextRegion();
r.Padding = { Before: 1, After: 2, Start: 3, End: 4, Unit: 1 };
const p = r.Padding;
p.End = 9;
r.Padding = p;
// An own property would mean the write never reached native.
return JSON.stringify(r.Padding) + ' own=' + r.hasOwnProperty('Padding');
})()",
);
assert_eq!(v, r#"{"Before":1,"After":2,"Start":3,"End":9,"Unit":1} own=false"#);
}
Loading
Loading