object_goslice_reflect_test.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. package goja
  2. import (
  3. "testing"
  4. )
  5. func TestGoSliceReflectBasic(t *testing.T) {
  6. const SCRIPT = `
  7. var sum = 0;
  8. for (var i = 0; i < a.length; i++) {
  9. sum += a[i];
  10. }
  11. sum;
  12. `
  13. r := New()
  14. r.Set("a", []int{1, 2, 3, 4})
  15. v, err := r.RunString(SCRIPT)
  16. if err != nil {
  17. t.Fatal(err)
  18. }
  19. if i := v.ToInteger(); i != 10 {
  20. t.Fatalf("Expected 10, got: %d", i)
  21. }
  22. }
  23. func TestGoSliceReflectIn(t *testing.T) {
  24. const SCRIPT = `
  25. var idx = "";
  26. for (var i in a) {
  27. idx += i;
  28. }
  29. idx;
  30. `
  31. r := New()
  32. r.Set("a", []int{1, 2, 3, 4})
  33. v, err := r.RunString(SCRIPT)
  34. if err != nil {
  35. t.Fatal(err)
  36. }
  37. if i := v.String(); i != "0123" {
  38. t.Fatalf("Expected '0123', got: '%s'", i)
  39. }
  40. }
  41. func TestGoSliceReflectSet(t *testing.T) {
  42. const SCRIPT = `
  43. a[0] = 33;
  44. a[1] = 333;
  45. a[2] = "42";
  46. a[3] = {};
  47. a[4] = 0;
  48. `
  49. r := New()
  50. a := []int8{1, 2, 3, 4}
  51. r.Set("a", a)
  52. _, err := r.RunString(SCRIPT)
  53. if err != nil {
  54. t.Fatal(err)
  55. }
  56. if a[0] != 33 {
  57. t.Fatalf("a[0] = %d, expected 33", a[0])
  58. }
  59. if a[1] != 77 {
  60. t.Fatalf("a[1] = %d, expected 77", a[1])
  61. }
  62. if a[2] != 42 {
  63. t.Fatalf("a[2] = %d, expected 42", a[2])
  64. }
  65. if a[3] != 0 {
  66. t.Fatalf("a[3] = %d, expected 0", a[3])
  67. }
  68. }
  69. func TestGoSliceReflectPush(t *testing.T) {
  70. r := New()
  71. t.Run("Can push to array by array ptr", func(t *testing.T) {
  72. a := []int8{1}
  73. r.Set("a", &a)
  74. _, err := r.RunString(`a.push (10)`)
  75. if err != nil {
  76. t.Fatal(err)
  77. }
  78. if a[1] != 10 {
  79. t.Fatalf("a[1] = %d, expected 10", a[1])
  80. }
  81. })
  82. t.Run("Can push to array by struct ptr", func(t *testing.T) {
  83. type testStr struct {
  84. A []int
  85. }
  86. a := testStr{
  87. A: []int{2},
  88. }
  89. r.Set("a", &a)
  90. _, err := r.RunString(`a.A.push (10)`)
  91. if err != nil {
  92. t.Fatal(err)
  93. }
  94. if a.A[1] != 10 {
  95. t.Fatalf("a[1] = %v, expected 10", a)
  96. }
  97. })
  98. }
  99. func TestGoSliceReflectProtoMethod(t *testing.T) {
  100. const SCRIPT = `
  101. a.join(",")
  102. `
  103. r := New()
  104. a := []int8{1, 2, 3, 4}
  105. r.Set("a", a)
  106. ret, err := r.RunString(SCRIPT)
  107. if err != nil {
  108. t.Fatal(err)
  109. }
  110. if s := ret.String(); s != "1,2,3,4" {
  111. t.Fatalf("Unexpected result: '%s'", s)
  112. }
  113. }
  114. type gosliceReflect_withMethods []interface{}
  115. func (s gosliceReflect_withMethods) Method() bool {
  116. return true
  117. }
  118. func TestGoSliceReflectMethod(t *testing.T) {
  119. const SCRIPT = `
  120. typeof a === "object" && a[0] === 42 && a.Method() === true;
  121. `
  122. vm := New()
  123. a := make(gosliceReflect_withMethods, 1)
  124. a[0] = 42
  125. vm.Set("a", a)
  126. v, err := vm.RunString(SCRIPT)
  127. if err != nil {
  128. t.Fatal(err)
  129. }
  130. if !v.StrictEquals(valueTrue) {
  131. t.Fatalf("Expected true, got %v", v)
  132. }
  133. }
  134. func TestGoSliceReflectGetStr(t *testing.T) {
  135. r := New()
  136. v := r.ToValue([]string{"test"})
  137. if o, ok := v.(*Object); ok {
  138. if e := o.Get("0").Export(); e != "test" {
  139. t.Fatalf("Unexpected o.Get(\"0\"): %v", e)
  140. }
  141. }
  142. }
  143. func TestGoSliceReflectNilObjectIfaceVal(t *testing.T) {
  144. r := New()
  145. a := []Value{(*Object)(nil)}
  146. r.Set("a", a)
  147. ret, err := r.RunString(`
  148. ""+a[0];
  149. `)
  150. if err != nil {
  151. t.Fatal(err)
  152. }
  153. if !asciiString("null").SameAs(ret) {
  154. t.Fatalf("ret: %v", ret)
  155. }
  156. }
  157. func TestGoSliceReflectSetLength(t *testing.T) {
  158. r := New()
  159. a := []int{1, 2, 3, 4}
  160. b := []testing.TB{&testing.T{}, &testing.T{}, (*testing.T)(nil)}
  161. r.Set("a", &a)
  162. r.Set("b", &b)
  163. _, err := r.RunString(`
  164. 'use strict';
  165. a.length = 3;
  166. if (a.length !== 3) {
  167. throw new Error("length="+a.length);
  168. }
  169. if (a[3] !== undefined) {
  170. throw new Error("a[3]="+a[3]);
  171. }
  172. a.length = 5;
  173. if (a.length !== 5) {
  174. throw new Error("a.length="+a.length);
  175. }
  176. if (a[3] !== 0) {
  177. throw new Error("a[3]="+a[3]);
  178. }
  179. if (a[4] !== 0) {
  180. throw new Error("a[4]="+a[4]);
  181. }
  182. b.length = 3;
  183. if (b.length !== 3) {
  184. throw new Error("b.length="+b.length);
  185. }
  186. if (b[3] !== undefined) {
  187. throw new Error("b[3]="+b[3]);
  188. }
  189. b.length = 5;
  190. if (b.length !== 5) {
  191. throw new Error("length="+b.length);
  192. }
  193. if (b[3] !== null) {
  194. throw new Error("b[3]="+b[3]);
  195. }
  196. if (b[4] !== null) {
  197. throw new Error("b[4]="+b[4]);
  198. }
  199. if (b[2] !== null) {
  200. throw new Error("b[2]="+b[2]);
  201. }
  202. `)
  203. if err != nil {
  204. t.Fatal(err)
  205. }
  206. }
  207. func TestGoSliceReflectProto(t *testing.T) {
  208. r := New()
  209. a := []*Object{{}, nil, {}}
  210. r.Set("a", &a)
  211. _, err := r.RunString(TESTLIB + `
  212. var proto = [,2,,4];
  213. Object.setPrototypeOf(a, proto);
  214. assert.sameValue(a[1], null, "a[1]");
  215. assert.sameValue(a[3], 4, "a[3]");
  216. var desc = Object.getOwnPropertyDescriptor(a, "1");
  217. assert.sameValue(desc.value, null, "desc.value");
  218. assert(desc.writable, "writable");
  219. assert(desc.enumerable, "enumerable");
  220. assert(!desc.configurable, "configurable");
  221. var v5;
  222. Object.defineProperty(proto, "5", {
  223. set: function(v) {
  224. v5 = v;
  225. }
  226. });
  227. a[5] = "test";
  228. assert.sameValue(v5, "test", "v5");
  229. `)
  230. if err != nil {
  231. t.Fatal(err)
  232. }
  233. }
  234. func TestGoSliceReflectProtoProto(t *testing.T) {
  235. r := New()
  236. a := []*Object{{}, nil, {}}
  237. proto := []*Object{{}, {}, {}, {}}
  238. r.Set("a", &a)
  239. r.Set("proto", proto)
  240. _, err := r.RunString(`
  241. "use strict";
  242. var protoproto = {};
  243. Object.defineProperty(protoproto, "3", {
  244. value: 42
  245. });
  246. Object.setPrototypeOf(proto, protoproto);
  247. Object.setPrototypeOf(a, proto);
  248. if (a.hasOwnProperty("3")) {
  249. throw new Error("a.hasOwnProperty(\"3\")");
  250. }
  251. if (a[3] !== null) {
  252. throw new Error("a[3]="+a[3]);
  253. }
  254. a[3] = null;
  255. if (a[3] !== null) {
  256. throw new Error("a[3]=" + a[3]);
  257. }
  258. `)
  259. if err != nil {
  260. t.Fatal(err)
  261. }
  262. }
  263. func TestGoSliceReflectDelete(t *testing.T) {
  264. r := New()
  265. a := []*Object{{}, nil, {}}
  266. r.Set("a", a)
  267. v, err := r.RunString(`
  268. delete a[0] && delete a[1] && delete a[3];
  269. `)
  270. if err != nil {
  271. t.Fatal(err)
  272. }
  273. if v != valueTrue {
  274. t.Fatalf("not true: %v", v)
  275. }
  276. }
  277. func TestGoSliceReflectPop(t *testing.T) {
  278. r := New()
  279. a := []string{"1", "", "3"}
  280. r.Set("a", &a)
  281. v, err := r.RunString(`
  282. a.pop()
  283. `)
  284. if err != nil {
  285. t.Fatal(err)
  286. }
  287. if !v.SameAs(asciiString("3")) {
  288. t.Fatal(v)
  289. }
  290. }
  291. func TestGoSliceReflectPopNoPtr(t *testing.T) {
  292. r := New()
  293. a := []string{"1", "", "3"}
  294. r.Set("a", a)
  295. v, err := r.RunString(`
  296. a.pop()
  297. `)
  298. if err != nil {
  299. t.Fatal(err)
  300. }
  301. if !v.SameAs(asciiString("3")) {
  302. t.Fatal(v)
  303. }
  304. }
  305. func TestGoSliceReflectLengthProperty(t *testing.T) {
  306. vm := New()
  307. vm.Set("s", []int{2, 3, 4})
  308. _, err := vm.RunString(`
  309. if (!s.hasOwnProperty("length")) {
  310. throw new Error("hasOwnProperty() returned false");
  311. }
  312. let desc = Object.getOwnPropertyDescriptor(s, "length");
  313. if (desc.value !== 3 || !desc.writable || desc.enumerable || desc.configurable) {
  314. throw new Error("incorrect property descriptor: " + JSON.stringify(desc));
  315. }
  316. `)
  317. if err != nil {
  318. t.Fatal(err)
  319. }
  320. }
  321. type testCustomSliceWithMethods []int
  322. func (a testCustomSliceWithMethods) Method() bool {
  323. return true
  324. }
  325. func TestGoSliceReflectMethods(t *testing.T) {
  326. vm := New()
  327. vm.Set("s", testCustomSliceWithMethods{1, 2, 3})
  328. _, err := vm.RunString(`
  329. if (!s.hasOwnProperty("Method")) {
  330. throw new Error("hasOwnProperty() returned false");
  331. }
  332. let desc = Object.getOwnPropertyDescriptor(s, "Method");
  333. if (desc.value() !== true || desc.writable || !desc.enumerable || desc.configurable) {
  334. throw new Error("incorrect property descriptor: " + JSON.stringify(desc));
  335. }
  336. `)
  337. if err != nil {
  338. t.Fatal(err)
  339. }
  340. }