Reflect.rs 7.9 KB

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