object_gomap_reflect_test.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. package goja
  2. import (
  3. "testing"
  4. )
  5. func TestGoMapReflectGetSet(t *testing.T) {
  6. const SCRIPT = `
  7. m.c = m.a + m.b;
  8. `
  9. vm := New()
  10. m := map[string]string{
  11. "a": "4",
  12. "b": "2",
  13. }
  14. vm.Set("m", m)
  15. _, err := vm.RunString(SCRIPT)
  16. if err != nil {
  17. t.Fatal(err)
  18. }
  19. if c := m["c"]; c != "42" {
  20. t.Fatalf("Unexpected value: '%s'", c)
  21. }
  22. }
  23. func TestGoMapReflectIntKey(t *testing.T) {
  24. const SCRIPT = `
  25. m[2] = m[0] + m[1];
  26. `
  27. vm := New()
  28. m := map[int]int{
  29. 0: 40,
  30. 1: 2,
  31. }
  32. vm.Set("m", m)
  33. _, err := vm.RunString(SCRIPT)
  34. if err != nil {
  35. t.Fatal(err)
  36. }
  37. if c := m[2]; c != 42 {
  38. t.Fatalf("Unexpected value: '%d'", c)
  39. }
  40. }
  41. func TestGoMapReflectDelete(t *testing.T) {
  42. const SCRIPT = `
  43. delete m.a;
  44. `
  45. vm := New()
  46. m := map[string]string{
  47. "a": "4",
  48. "b": "2",
  49. }
  50. vm.Set("m", m)
  51. _, err := vm.RunString(SCRIPT)
  52. if err != nil {
  53. t.Fatal(err)
  54. }
  55. if _, exists := m["a"]; exists {
  56. t.Fatal("a still exists")
  57. }
  58. if b := m["b"]; b != "2" {
  59. t.Fatalf("Unexpected b: '%s'", b)
  60. }
  61. }
  62. func TestGoMapReflectJSON(t *testing.T) {
  63. const SCRIPT = `
  64. function f(m) {
  65. return JSON.stringify(m);
  66. }
  67. `
  68. vm := New()
  69. m := map[string]string{
  70. "t": "42",
  71. }
  72. _, err := vm.RunString(SCRIPT)
  73. if err != nil {
  74. t.Fatal(err)
  75. }
  76. f := vm.Get("f")
  77. if call, ok := AssertFunction(f); ok {
  78. v, err := call(nil, ([]Value{vm.ToValue(m)})...)
  79. if err != nil {
  80. t.Fatal(err)
  81. }
  82. if !v.StrictEquals(asciiString(`{"t":"42"}`)) {
  83. t.Fatalf("Unexpected value: %v", v)
  84. }
  85. } else {
  86. t.Fatalf("Not a function: %v", f)
  87. }
  88. }
  89. func TestGoMapReflectProto(t *testing.T) {
  90. const SCRIPT = `
  91. m.hasOwnProperty("t");
  92. `
  93. vm := New()
  94. m := map[string]string{
  95. "t": "42",
  96. }
  97. vm.Set("m", m)
  98. v, err := vm.RunString(SCRIPT)
  99. if err != nil {
  100. t.Fatal(err)
  101. }
  102. if !v.StrictEquals(valueTrue) {
  103. t.Fatalf("Expected true, got %v", v)
  104. }
  105. }
  106. type gomapReflect_noMethods map[string]interface{}
  107. type gomapReflect_withMethods map[string]interface{}
  108. func (m gomapReflect_withMethods) Method() bool {
  109. return true
  110. }
  111. func TestGoMapReflectNoMethods(t *testing.T) {
  112. const SCRIPT = `
  113. typeof m === "object" && m.hasOwnProperty("t") && m.t === 42;
  114. `
  115. vm := New()
  116. m := make(gomapReflect_noMethods)
  117. m["t"] = 42
  118. vm.Set("m", m)
  119. v, err := vm.RunString(SCRIPT)
  120. if err != nil {
  121. t.Fatal(err)
  122. }
  123. if !v.StrictEquals(valueTrue) {
  124. t.Fatalf("Expected true, got %v", v)
  125. }
  126. }
  127. func TestGoMapReflectWithMethods(t *testing.T) {
  128. const SCRIPT = `
  129. typeof m === "object" && !m.hasOwnProperty("t") && m.hasOwnProperty("Method") && m.Method();
  130. `
  131. vm := New()
  132. m := make(gomapReflect_withMethods)
  133. m["t"] = 42
  134. vm.Set("m", m)
  135. v, err := vm.RunString(SCRIPT)
  136. if err != nil {
  137. t.Fatal(err)
  138. }
  139. if !v.StrictEquals(valueTrue) {
  140. t.Fatalf("Expected true, got %v", v)
  141. }
  142. }
  143. func TestGoMapReflectWithProto(t *testing.T) {
  144. vm := New()
  145. m := map[string]string{
  146. "t": "42",
  147. }
  148. vm.Set("m", m)
  149. _, err := vm.RunString(TESTLIB + `
  150. (function() {
  151. 'use strict';
  152. var proto = {};
  153. var getterAllowed = false;
  154. var setterAllowed = false;
  155. var tHolder = "proto t";
  156. Object.defineProperty(proto, "t", {
  157. get: function() {
  158. if (!getterAllowed) throw new Error("getter is called");
  159. return tHolder;
  160. },
  161. set: function(v) {
  162. if (!setterAllowed) throw new Error("setter is called");
  163. tHolder = v;
  164. }
  165. });
  166. var t1Holder;
  167. Object.defineProperty(proto, "t1", {
  168. get: function() {
  169. return t1Holder;
  170. },
  171. set: function(v) {
  172. t1Holder = v;
  173. }
  174. });
  175. Object.setPrototypeOf(m, proto);
  176. assert.sameValue(m.t, "42");
  177. m.t = 43;
  178. assert.sameValue(m.t, "43");
  179. t1Holder = "test";
  180. assert.sameValue(m.t1, "test");
  181. m.t1 = "test1";
  182. assert.sameValue(m.t1, "test1");
  183. delete m.t;
  184. getterAllowed = true;
  185. assert.sameValue(m.t, "proto t", "after delete");
  186. setterAllowed = true;
  187. m.t = true;
  188. assert.sameValue(m.t, true, "m.t === true");
  189. assert.sameValue(tHolder, true, "tHolder === true");
  190. Object.preventExtensions(m);
  191. assert.throws(TypeError, function() {
  192. m.t2 = 1;
  193. });
  194. m.t1 = "test2";
  195. assert.sameValue(m.t1, "test2");
  196. })();
  197. `)
  198. if err != nil {
  199. t.Fatal(err)
  200. }
  201. }
  202. func TestGoMapReflectProtoProp(t *testing.T) {
  203. const SCRIPT = `
  204. (function() {
  205. "use strict";
  206. var proto = {};
  207. Object.defineProperty(proto, "ro", {value: 42});
  208. Object.setPrototypeOf(m, proto);
  209. assert.throws(TypeError, function() {
  210. m.ro = 43;
  211. });
  212. Object.defineProperty(m, "ro", {value: 43});
  213. assert.sameValue(m.ro, "43");
  214. })();
  215. `
  216. r := New()
  217. r.Set("m", map[string]string{})
  218. _, err := r.RunString(TESTLIB + SCRIPT)
  219. if err != nil {
  220. t.Fatal(err)
  221. }
  222. }
  223. func TestGoMapReflectUnicode(t *testing.T) {
  224. const SCRIPT = `
  225. Object.setPrototypeOf(m, s);
  226. if (m.Тест !== "passed") {
  227. throw new Error("m.Тест: " + m.Тест);
  228. }
  229. m["é"];
  230. `
  231. type S struct {
  232. Тест string
  233. }
  234. vm := New()
  235. m := map[string]int{
  236. "é": 42,
  237. }
  238. s := S{
  239. Тест: "passed",
  240. }
  241. vm.Set("m", m)
  242. vm.Set("s", &s)
  243. res, err := vm.RunString(SCRIPT)
  244. if err != nil {
  245. t.Fatal(err)
  246. }
  247. if res == nil || !res.StrictEquals(valueInt(42)) {
  248. t.Fatalf("Unexpected value: %v", res)
  249. }
  250. }