Object.rs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. use js_sys::*;
  2. use std::f64::NAN;
  3. use wasm_bindgen::prelude::*;
  4. use wasm_bindgen::JsCast;
  5. use wasm_bindgen_test::*;
  6. #[wasm_bindgen]
  7. extern "C" {
  8. type Foo42;
  9. #[wasm_bindgen(method, setter, structural)]
  10. fn set_foo(this: &Foo42, val: JsValue);
  11. #[wasm_bindgen(js_name = prototype, js_namespace = Object)]
  12. static OBJECT_PROTOTYPE: JsValue;
  13. #[wasm_bindgen(js_name = prototype, js_namespace = Array)]
  14. static ARRAY_PROTOTYPE: JsValue;
  15. type DefinePropertyAttrs;
  16. #[wasm_bindgen(method, setter, structural)]
  17. fn set_value(this: &DefinePropertyAttrs, val: &JsValue);
  18. type PropertyDescriptor;
  19. #[wasm_bindgen(method, getter, structural)]
  20. fn value(this: &PropertyDescriptor) -> JsValue;
  21. }
  22. #[wasm_bindgen(module = "tests/wasm/Object.js")]
  23. extern "C" {
  24. fn map_with_symbol_key() -> Object;
  25. fn symbol_key() -> JsValue;
  26. type Foo;
  27. #[wasm_bindgen(constructor)]
  28. fn new() -> Foo;
  29. #[wasm_bindgen(js_name = prototype, js_namespace = Foo)]
  30. static FOO_PROTOTYPE: Object;
  31. #[wasm_bindgen(js_name = prototype, js_namespace = Bar)]
  32. static BAR_PROTOTYPE: Object;
  33. }
  34. fn foo_42() -> Object {
  35. let foo = Foo42::from(JsValue::from(Object::new()));
  36. foo.set_foo(42.into());
  37. JsValue::from(foo).into()
  38. }
  39. #[wasm_bindgen_test]
  40. fn new() {
  41. assert!(JsValue::from(Object::new()).is_object());
  42. }
  43. #[wasm_bindgen_test]
  44. fn assign() {
  45. let a = JsValue::from("a");
  46. let b = JsValue::from("b");
  47. let c = JsValue::from("c");
  48. let target = Object::new();
  49. Reflect::set(target.as_ref(), a.as_ref(), a.as_ref()).unwrap();
  50. let src1 = Object::new();
  51. Reflect::set(src1.as_ref(), &a, &c).unwrap();
  52. let src2 = Object::new();
  53. Reflect::set(src2.as_ref(), &b, &b).unwrap();
  54. let src3 = Object::new();
  55. Reflect::set(src3.as_ref(), &c, &c).unwrap();
  56. let res = Object::assign3(&target, &src1, &src2, &src3);
  57. assert!(Object::is(target.as_ref(), res.as_ref()));
  58. assert_eq!(Reflect::get(target.as_ref(), &a).unwrap(), c);
  59. assert_eq!(Reflect::get(target.as_ref(), &b).unwrap(), b);
  60. assert_eq!(Reflect::get(target.as_ref(), &c).unwrap(), c);
  61. }
  62. #[wasm_bindgen_test]
  63. fn create() {
  64. let array_proto = eval("Array.prototype")
  65. .unwrap()
  66. .dyn_into::<Object>()
  67. .unwrap();
  68. let my_array = Object::create(&array_proto);
  69. assert!(my_array.is_instance_of::<Array>());
  70. }
  71. #[wasm_bindgen_test]
  72. fn define_property() {
  73. let value = DefinePropertyAttrs::from(JsValue::from(Object::new()));
  74. value.set_value(&43.into());
  75. let descriptor = Object::from(JsValue::from(value));
  76. let foo = foo_42();
  77. let foo = Object::define_property(&foo, &"bar".into(), &descriptor);
  78. assert!(foo.has_own_property(&"bar".into()));
  79. }
  80. #[wasm_bindgen_test]
  81. fn define_properties() {
  82. let props = Object::new();
  83. let descriptor = DefinePropertyAttrs::from(JsValue::from(Object::new()));
  84. descriptor.set_value(&42.into());
  85. let descriptor = JsValue::from(descriptor);
  86. Reflect::set(props.as_ref(), &JsValue::from("bar"), &descriptor).unwrap();
  87. Reflect::set(props.as_ref(), &JsValue::from("car"), &descriptor).unwrap();
  88. let foo = foo_42();
  89. let foo = Object::define_properties(&foo, &props);
  90. assert!(foo.has_own_property(&"bar".into()));
  91. assert!(foo.has_own_property(&"car".into()));
  92. }
  93. #[wasm_bindgen_test]
  94. fn entries() {
  95. let entries = Object::entries(&foo_42());
  96. assert_eq!(entries.length(), 1);
  97. entries.for_each(&mut |x, _, _| {
  98. assert!(x.is_object());
  99. let array: Array = x.into();
  100. assert_eq!(array.shift(), "foo");
  101. assert_eq!(array.shift(), 42);
  102. assert_eq!(array.length(), 0);
  103. });
  104. }
  105. #[wasm_bindgen_test]
  106. fn from_entries() {
  107. let array = Array::new();
  108. let entry_one = Array::new();
  109. let entry_two = Array::new();
  110. entry_one.push(&"foo".into());
  111. entry_one.push(&"bar".into());
  112. entry_two.push(&"baz".into());
  113. entry_two.push(&42.into());
  114. array.push(&entry_one);
  115. array.push(&entry_two);
  116. let object = Object::from_entries(&array).unwrap();
  117. assert_eq!(Reflect::get(object.as_ref(), &"foo".into()).unwrap(), "bar");
  118. assert_eq!(Reflect::get(object.as_ref(), &"baz".into()).unwrap(), 42);
  119. let not_iterable = Object::new();
  120. let error = Object::from_entries(&not_iterable).unwrap_err();
  121. assert!(error.is_instance_of::<TypeError>());
  122. }
  123. #[wasm_bindgen_test]
  124. fn get_own_property_descriptor() {
  125. let foo = foo_42();
  126. let desc = Object::get_own_property_descriptor(&foo, &"foo".into());
  127. assert_eq!(PropertyDescriptor::from(desc).value(), 42);
  128. let desc = Object::get_own_property_descriptor(&foo, &"bar".into());
  129. assert!(desc.is_undefined());
  130. }
  131. #[wasm_bindgen_test]
  132. fn get_own_property_descriptors() {
  133. let foo = foo_42();
  134. let descriptors = Object::get_own_property_descriptors(&foo);
  135. let foo_desc = Reflect::get(&descriptors, &"foo".into()).unwrap();
  136. assert_eq!(PropertyDescriptor::from(foo_desc).value(), 42);
  137. }
  138. #[wasm_bindgen_test]
  139. fn get_own_property_names() {
  140. let names = Object::get_own_property_names(&foo_42());
  141. assert_eq!(names.length(), 1);
  142. names.for_each(&mut |x, _, _| {
  143. assert_eq!(x, "foo");
  144. });
  145. }
  146. #[wasm_bindgen_test]
  147. fn get_own_property_symbols() {
  148. let symbols = Object::get_own_property_symbols(&map_with_symbol_key());
  149. assert_eq!(symbols.length(), 1);
  150. }
  151. #[wasm_bindgen_test]
  152. fn get_prototype_of() {
  153. let proto = JsValue::from(Object::get_prototype_of(&Object::new().into()));
  154. assert_eq!(proto, *OBJECT_PROTOTYPE);
  155. let proto = JsValue::from(Object::get_prototype_of(&Array::new().into()));
  156. assert_eq!(proto, *ARRAY_PROTOTYPE);
  157. }
  158. #[wasm_bindgen_test]
  159. fn has_own_property() {
  160. assert!(foo_42().has_own_property(&"foo".into()));
  161. assert!(!foo_42().has_own_property(&"bar".into()));
  162. assert!(map_with_symbol_key().has_own_property(&symbol_key()));
  163. }
  164. #[wasm_bindgen_test]
  165. fn has_own() {
  166. assert!(Object::has_own(&foo_42(), &"foo".into()));
  167. assert!(!Object::has_own(&foo_42(), &"bar".into()));
  168. assert!(Object::has_own(&map_with_symbol_key(), &symbol_key()));
  169. }
  170. #[wasm_bindgen_test]
  171. fn to_string() {
  172. assert_eq!(Object::new().to_string(), "[object Object]");
  173. assert_eq!(foo_42().to_string(), "[object Object]");
  174. }
  175. #[wasm_bindgen_test]
  176. fn is() {
  177. let object = JsValue::from(Object::new());
  178. assert!(Object::is(&object, &object));
  179. assert!(Object::is(&JsValue::undefined(), &JsValue::undefined()));
  180. assert!(Object::is(&JsValue::null(), &JsValue::null()));
  181. assert!(Object::is(&JsValue::TRUE, &JsValue::TRUE));
  182. assert!(Object::is(&JsValue::FALSE, &JsValue::FALSE));
  183. assert!(Object::is(&"foo".into(), &"foo".into()));
  184. assert!(Object::is(&JsValue::from(42), &JsValue::from(42)));
  185. assert!(Object::is(&JsValue::from(NAN), &JsValue::from(NAN)));
  186. let another_object = JsValue::from(Object::new());
  187. assert!(!Object::is(&object, &another_object));
  188. assert!(!Object::is(&JsValue::TRUE, &JsValue::FALSE));
  189. assert!(!Object::is(&"foo".into(), &"bar".into()));
  190. assert!(!Object::is(&JsValue::from(23), &JsValue::from(42)));
  191. }
  192. #[wasm_bindgen_test]
  193. fn is_extensible() {
  194. let object = Object::new();
  195. assert!(Object::is_extensible(&object));
  196. Object::prevent_extensions(&object);
  197. assert!(!Object::is_extensible(&object));
  198. }
  199. #[wasm_bindgen_test]
  200. fn is_frozen() {
  201. let object = Object::new();
  202. assert!(!Object::is_frozen(&object));
  203. Object::freeze(&object);
  204. assert!(Object::is_frozen(&object));
  205. }
  206. #[wasm_bindgen_test]
  207. fn is_sealed() {
  208. let object = Object::new();
  209. assert!(!Object::is_sealed(&object));
  210. Object::seal(&object);
  211. assert!(Object::is_sealed(&object));
  212. }
  213. #[wasm_bindgen_test]
  214. fn is_prototype_of() {
  215. let foo = JsValue::from(Foo::new());
  216. assert!(FOO_PROTOTYPE.is_prototype_of(&foo));
  217. assert!(!BAR_PROTOTYPE.is_prototype_of(&foo));
  218. }
  219. #[wasm_bindgen_test]
  220. fn keys() {
  221. let keys = Object::keys(&foo_42());
  222. assert_eq!(keys.length(), 1);
  223. keys.for_each(&mut |x, _, _| {
  224. assert_eq!(x, "foo");
  225. });
  226. }
  227. #[wasm_bindgen_test]
  228. fn values() {
  229. let values = Object::values(&foo_42());
  230. assert_eq!(values.length(), 1);
  231. values.for_each(&mut |x, _, _| {
  232. assert_eq!(x, 42);
  233. });
  234. }
  235. #[wasm_bindgen_test]
  236. fn property_is_enumerable() {
  237. assert!(foo_42().property_is_enumerable(&"foo".into()));
  238. assert!(!foo_42().property_is_enumerable(&42.into()));
  239. assert!(!Object::new().property_is_enumerable(&"foo".into()));
  240. }
  241. #[wasm_bindgen_test]
  242. fn set_prototype_of() {
  243. let a = foo_42();
  244. let b = foo_42();
  245. Object::set_prototype_of(&a, &b);
  246. assert!(b.is_prototype_of(&a.into()));
  247. }
  248. #[wasm_bindgen_test]
  249. fn to_locale_string() {
  250. assert_eq!(Object::new().to_locale_string(), "[object Object]");
  251. }
  252. #[wasm_bindgen_test]
  253. fn value_of() {
  254. let a = JsValue::from(foo_42());
  255. let b = JsValue::from(foo_42());
  256. let a2 = JsValue::from(Object::from(a.clone()).value_of());
  257. assert_eq!(a, a);
  258. assert_eq!(a, a2);
  259. assert_ne!(a, b);
  260. assert_ne!(a2, b);
  261. }