1 use js_sys::*;
2 use wasm_bindgen::prelude::*;
3 use wasm_bindgen_test::*;
4 
5 #[wasm_bindgen(module = "tests/wasm/Reflect.js")]
6 extern "C" {
get_char_at() -> Function7     fn get_char_at() -> Function;
8 
9     #[wasm_bindgen(js_name = Rectangle)]
10     static RECTANGLE_CLASS: Function;
11     #[wasm_bindgen(js_name = Rectangle2)]
12     static RECTANGLE2_CLASS: Function;
13 
14     #[derive(Clone)]
15     type Rectangle;
16     #[wasm_bindgen(constructor)]
new() -> Rectangle17     fn new() -> Rectangle;
18     #[wasm_bindgen(method, getter, structural)]
x(this: &Rectangle) -> u3219     fn x(this: &Rectangle) -> u32;
20     #[wasm_bindgen(method, getter, structural, js_name = x)]
x_jsval(this: &Rectangle) -> JsValue21     fn x_jsval(this: &Rectangle) -> JsValue;
22     #[wasm_bindgen(method, setter, structural)]
set_x(this: &Rectangle, x: u32)23     fn set_x(this: &Rectangle, x: u32);
24 
throw_all_the_time() -> Object25     fn throw_all_the_time() -> Object;
26 }
27 
28 #[wasm_bindgen]
29 extern "C" {
30     #[wasm_bindgen(js_name = prototype, js_namespace = Object)]
31     static OBJECT_PROTOTYPE: JsValue;
32     #[wasm_bindgen(js_name = prototype, js_namespace = Array)]
33     static ARRAY_PROTOTYPE: JsValue;
34 
35     type DefinePropertyAttrs;
36     #[wasm_bindgen(method, setter, structural)]
set_value(this: &DefinePropertyAttrs, val: &JsValue)37     fn set_value(this: &DefinePropertyAttrs, val: &JsValue);
38 
39     type PropertyDescriptor;
40     #[wasm_bindgen(method, getter, structural)]
value(this: &PropertyDescriptor) -> JsValue41     fn value(this: &PropertyDescriptor) -> JsValue;
42 }
43 
44 #[wasm_bindgen_test]
apply()45 fn apply() {
46     let args = Array::new();
47     args.push(&3.into());
48     assert_eq!(
49         Reflect::apply(&get_char_at(), &"ponies".into(), &args).unwrap(),
50         "i"
51     );
52 }
53 
54 #[wasm_bindgen_test]
construct()55 fn construct() {
56     let args = Array::new();
57     args.push(&10.into());
58     args.push(&10.into());
59     let instance = Reflect::construct(&RECTANGLE_CLASS, &args).unwrap();
60     assert_eq!(Rectangle::from(instance).x(), 10);
61 }
62 
63 #[wasm_bindgen_test]
construct_with_new_target()64 fn construct_with_new_target() {
65     let args = Array::new();
66     args.push(&10.into());
67     args.push(&10.into());
68     let instance =
69         Reflect::construct_with_new_target(&RECTANGLE_CLASS, &args, &RECTANGLE2_CLASS).unwrap();
70     assert_eq!(Rectangle::from(instance).x(), 10);
71 }
72 
73 #[wasm_bindgen_test]
define_property()74 fn define_property() {
75     let value = DefinePropertyAttrs::from(JsValue::from(Object::new()));
76     value.set_value(&42.into());
77     let obj = Object::from(JsValue::from(value));
78     assert!(Reflect::define_property(&obj, &"key".into(), &obj).unwrap());
79 }
80 
81 #[wasm_bindgen_test]
delete_property()82 fn delete_property() {
83     let r = Rectangle::new();
84     r.set_x(10);
85 
86     let obj = Object::from(JsValue::from(r.clone()));
87     Reflect::delete_property(&obj, &"x".into()).unwrap();
88     assert!(r.x_jsval().is_undefined());
89 
90     let array = Array::new();
91     array.push(&1.into());
92     let obj = Object::from(JsValue::from(array));
93     Reflect::delete_property(&obj, &0.into()).unwrap();
94     let array = Array::from(&JsValue::from(obj));
95     assert!(array.length() == 1);
96     array.for_each(&mut |x, _, _| assert!(x.is_undefined()));
97 }
98 
99 #[wasm_bindgen_test]
get()100 fn get() {
101     let r = Rectangle::new();
102     r.set_x(10);
103 
104     let obj = JsValue::from(r.clone());
105     assert_eq!(Reflect::get(&obj, &"x".into()).unwrap(), 10);
106 }
107 
108 #[wasm_bindgen_test]
get_f64()109 fn get_f64() {
110     let a = Array::new();
111     assert_eq!(Reflect::get_f64(&a, 0.0).unwrap(), JsValue::UNDEFINED);
112     assert_eq!(a.push(&JsValue::from_str("Hi!")), 1);
113     assert_eq!(Reflect::get_f64(&a, 0.0).unwrap(), JsValue::from_str("Hi!"));
114 }
115 
116 #[wasm_bindgen_test]
get_u32()117 fn get_u32() {
118     let a = Array::new();
119     assert_eq!(Reflect::get_u32(&a, 0).unwrap(), JsValue::UNDEFINED);
120     assert_eq!(a.push(&JsValue::from_str("Hi!")), 1);
121     assert_eq!(Reflect::get_u32(&a, 0).unwrap(), JsValue::from_str("Hi!"));
122 }
123 
124 #[wasm_bindgen_test]
get_own_property_descriptor()125 fn get_own_property_descriptor() {
126     let r = Rectangle::new();
127     r.set_x(10);
128 
129     let obj = Object::from(JsValue::from(r.clone()));
130     let desc = Reflect::get_own_property_descriptor(&obj, &"x".into()).unwrap();
131     assert_eq!(PropertyDescriptor::from(desc).value(), 10);
132     let desc = Reflect::get_own_property_descriptor(&obj, &"foo".into()).unwrap();
133     assert!(desc.is_undefined());
134 }
135 
136 #[wasm_bindgen_test]
get_prototype_of()137 fn get_prototype_of() {
138     let proto = JsValue::from(Reflect::get_prototype_of(&Object::new().into()).unwrap());
139     assert_eq!(proto, *OBJECT_PROTOTYPE);
140     let proto = JsValue::from(Reflect::get_prototype_of(&Array::new().into()).unwrap());
141     assert_eq!(proto, *ARRAY_PROTOTYPE);
142 }
143 
144 #[wasm_bindgen_test]
has()145 fn has() {
146     let obj = JsValue::from(Rectangle::new());
147     assert!(Reflect::has(&obj, &"x".into()).unwrap());
148     assert!(!Reflect::has(&obj, &"foo".into()).unwrap());
149 }
150 
151 #[wasm_bindgen_test]
is_extensible()152 fn is_extensible() {
153     let obj = Object::from(JsValue::from(Rectangle::new()));
154     assert!(Reflect::is_extensible(&obj).unwrap());
155     Reflect::prevent_extensions(&obj).unwrap();
156     assert!(!Reflect::is_extensible(&obj).unwrap());
157     let obj = Object::seal(&Object::new());
158     assert!(!Reflect::is_extensible(&obj).unwrap());
159 }
160 
161 #[wasm_bindgen_test]
own_keys()162 fn own_keys() {
163     let obj = JsValue::from(Rectangle::new());
164     let keys = Reflect::own_keys(&obj).unwrap();
165     assert!(keys.length() == 2);
166     keys.for_each(&mut |k, _, _| {
167         assert!(k == "x" || k == "y");
168     });
169 }
170 
171 #[wasm_bindgen_test]
prevent_extensions()172 fn prevent_extensions() {
173     let obj = Object::new();
174     Reflect::prevent_extensions(&obj).unwrap();
175     assert!(!Reflect::is_extensible(&obj).unwrap());
176 }
177 
178 #[wasm_bindgen_test]
set()179 fn set() {
180     let obj = JsValue::from(Object::new());
181     assert!(Reflect::set(&obj, &"key".into(), &"value".into()).unwrap());
182     assert_eq!(Reflect::get(&obj, &"key".into()).unwrap(), "value");
183 }
184 
185 #[wasm_bindgen_test]
set_f64()186 fn set_f64() {
187     let a = Array::new();
188     a.push(&JsValue::from_str("Hi!"));
189 
190     assert_eq!(Reflect::get_f64(&a, 0.0).unwrap(), JsValue::from_str("Hi!"));
191 
192     Reflect::set_f64(&a, 0.0, &JsValue::from_str("Bye!")).unwrap();
193 
194     assert_eq!(
195         Reflect::get_f64(&a, 0.0).unwrap(),
196         JsValue::from_str("Bye!")
197     );
198 }
199 
200 #[wasm_bindgen_test]
set_u32()201 fn set_u32() {
202     let a = Array::new();
203     a.push(&JsValue::from_str("Hi!"));
204 
205     assert_eq!(Reflect::get_u32(&a, 0).unwrap(), JsValue::from_str("Hi!"));
206 
207     Reflect::set_u32(&a, 0, &JsValue::from_str("Bye!")).unwrap();
208 
209     assert_eq!(Reflect::get_u32(&a, 0).unwrap(), JsValue::from_str("Bye!"));
210 }
211 
212 #[wasm_bindgen_test]
set_with_receiver()213 fn set_with_receiver() {
214     let obj1 = JsValue::from(Object::new());
215     let obj2 = JsValue::from(Object::new());
216     assert!(Reflect::set_with_receiver(&obj2, &"key".into(), &"value".into(), &obj2).unwrap());
217     assert!(Reflect::get(&obj1, &"key".into()).unwrap().is_undefined());
218     assert_eq!(Reflect::get(&obj2, &"key".into()).unwrap(), "value");
219 }
220 
221 #[wasm_bindgen_test]
set_prototype_of()222 fn set_prototype_of() {
223     let obj = Object::new();
224     assert!(Reflect::set_prototype_of(&obj, &JsValue::null()).unwrap());
225     let obj = JsValue::from(obj);
226     assert_eq!(
227         JsValue::from(Reflect::get_prototype_of(&obj).unwrap()),
228         JsValue::null()
229     );
230 }
231 
232 #[wasm_bindgen_test]
reflect_bindings_handle_proxies_that_just_throw_for_everything()233 fn reflect_bindings_handle_proxies_that_just_throw_for_everything() {
234     let p = throw_all_the_time();
235 
236     let desc = Object::new();
237     Reflect::set(desc.as_ref(), &"value".into(), &1.into()).unwrap();
238     assert!(Reflect::define_property(&p, &"a".into(), &desc).is_err());
239 
240     assert!(Reflect::delete_property(&p, &"a".into()).is_err());
241 
242     assert!(Reflect::get(p.as_ref(), &"a".into()).is_err());
243     assert!(Reflect::get_f64(p.as_ref(), 0.0).is_err());
244     assert!(Reflect::get_u32(p.as_ref(), 0).is_err());
245 
246     assert!(Reflect::get_own_property_descriptor(&p, &"a".into()).is_err());
247 
248     assert!(Reflect::get_prototype_of(p.as_ref()).is_err());
249 
250     assert!(Reflect::has(p.as_ref(), &"a".into()).is_err());
251 
252     assert!(Reflect::is_extensible(&p).is_err());
253 
254     assert!(Reflect::own_keys(p.as_ref()).is_err());
255 
256     assert!(Reflect::prevent_extensions(&p).is_err());
257 
258     assert!(Reflect::set(p.as_ref(), &"a".into(), &1.into()).is_err());
259     assert!(Reflect::set_f64(p.as_ref(), 0.0, &1.into()).is_err());
260     assert!(Reflect::set_u32(p.as_ref(), 0, &1.into()).is_err());
261 
262     assert!(Reflect::set_prototype_of(&p, Object::new().as_ref()).is_err());
263 }
264