object_goslice_test.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. package goja
  2. import (
  3. "testing"
  4. )
  5. func TestGoSliceBasic(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", []interface{}{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 TestGoSliceIn(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", []interface{}{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 TestGoSliceExpand(t *testing.T) {
  42. const SCRIPT = `
  43. var l = a.length;
  44. for (var i = 0; i < l; i++) {
  45. a[l + i] = a[i] * 2;
  46. }
  47. var sum = 0;
  48. for (var i = 0; i < a.length; i++) {
  49. sum += a[i];
  50. }
  51. sum;
  52. `
  53. r := New()
  54. a := []interface{}{int64(1), int64(2), int64(3), int64(4)}
  55. r.Set("a", &a)
  56. v, err := r.RunString(SCRIPT)
  57. if err != nil {
  58. t.Fatal(err)
  59. }
  60. sum := int64(0)
  61. for _, v := range a {
  62. sum += v.(int64)
  63. }
  64. if i := v.ToInteger(); i != sum {
  65. t.Fatalf("Expected %d, got: %d", sum, i)
  66. }
  67. }
  68. func TestGoSliceProtoMethod(t *testing.T) {
  69. const SCRIPT = `
  70. a.join(",")
  71. `
  72. r := New()
  73. a := []interface{}{1, 2, 3, 4}
  74. r.Set("a", a)
  75. ret, err := r.RunString(SCRIPT)
  76. if err != nil {
  77. t.Fatal(err)
  78. }
  79. if s := ret.String(); s != "1,2,3,4" {
  80. t.Fatalf("Unexpected result: '%s'", s)
  81. }
  82. }
  83. func TestGoSliceSetLength(t *testing.T) {
  84. r := New()
  85. a := []interface{}{1, 2, 3, 4}
  86. r.Set("a", &a)
  87. _, err := r.RunString(`
  88. 'use strict';
  89. a.length = 3;
  90. if (a.length !== 3) {
  91. throw new Error("length="+a.length);
  92. }
  93. if (a[3] !== undefined) {
  94. throw new Error("a[3](1)="+a[3]);
  95. }
  96. a.length = 5;
  97. if (a.length !== 5) {
  98. throw new Error("length="+a.length);
  99. }
  100. if (a[3] !== null) {
  101. throw new Error("a[3](2)="+a[3]);
  102. }
  103. if (a[4] !== null) {
  104. throw new Error("a[4]="+a[4]);
  105. }
  106. `)
  107. if err != nil {
  108. t.Fatal(err)
  109. }
  110. }
  111. func TestGoSliceProto(t *testing.T) {
  112. r := New()
  113. a := []interface{}{1, nil, 3}
  114. r.Set("a", &a)
  115. r.testScriptWithTestLib(`
  116. var proto = [,2,,4];
  117. Object.setPrototypeOf(a, proto);
  118. assert.sameValue(a[1], null, "a[1]");
  119. assert.sameValue(a[3], 4, "a[3]");
  120. var desc = Object.getOwnPropertyDescriptor(a, "1");
  121. assert.sameValue(desc.value, null, "desc.value");
  122. assert(desc.writable, "writable");
  123. assert(desc.enumerable, "enumerable");
  124. assert(!desc.configurable, "configurable");
  125. var v5;
  126. Object.defineProperty(proto, "5", {
  127. set: function(v) {
  128. v5 = v;
  129. }
  130. });
  131. a[5] = "test";
  132. assert.sameValue(v5, "test", "v5");
  133. `, _undefined, t)
  134. }
  135. func TestGoSliceProtoProto(t *testing.T) {
  136. r := New()
  137. a := []interface{}{1, nil, 3}
  138. proto := []interface{}{1, 2, 3, 4}
  139. r.Set("a", &a)
  140. r.Set("proto", proto)
  141. _, err := r.RunString(`
  142. "use strict";
  143. var protoproto = Object.create(null);
  144. Object.defineProperty(protoproto, "3", {
  145. value: 42
  146. });
  147. Object.setPrototypeOf(proto, protoproto);
  148. Object.setPrototypeOf(a, proto);
  149. a[3] = 11;
  150. if (a[3] !== 11) {
  151. throw new Error("a[3]=" + a[3]);
  152. }
  153. `)
  154. if err != nil {
  155. t.Fatal(err)
  156. }
  157. }
  158. func TestGoSliceDelete(t *testing.T) {
  159. r := New()
  160. a := []interface{}{1, nil, 3}
  161. r.Set("a", a)
  162. v, err := r.RunString(`
  163. delete a[0] && delete a[1] && delete a[3];
  164. `)
  165. if err != nil {
  166. t.Fatal(err)
  167. }
  168. if v != valueTrue {
  169. t.Fatalf("not true: %v", v)
  170. }
  171. }
  172. func TestGoSlicePop(t *testing.T) {
  173. r := New()
  174. a := []interface{}{1, nil, 3}
  175. r.Set("a", &a)
  176. v, err := r.RunString(`
  177. a.pop()
  178. `)
  179. if err != nil {
  180. t.Fatal(err)
  181. }
  182. if !v.SameAs(intToValue(3)) {
  183. t.Fatal(v)
  184. }
  185. }
  186. func TestGoSlicePopNoPtr(t *testing.T) {
  187. r := New()
  188. a := []interface{}{1, nil, 3}
  189. r.Set("a", a)
  190. v, err := r.RunString(`
  191. a.pop()
  192. `)
  193. if err != nil {
  194. t.Fatal(err)
  195. }
  196. if !v.SameAs(intToValue(3)) {
  197. t.Fatal(v)
  198. }
  199. }
  200. func TestGoSliceShift(t *testing.T) {
  201. r := New()
  202. a := []interface{}{1, nil, 3}
  203. r.Set("a", &a)
  204. v, err := r.RunString(`
  205. a.shift()
  206. `)
  207. if err != nil {
  208. t.Fatal(err)
  209. }
  210. if !v.SameAs(intToValue(1)) {
  211. t.Fatal(v)
  212. }
  213. }
  214. func TestGoSliceLengthProperty(t *testing.T) {
  215. vm := New()
  216. vm.Set("s", []interface{}{2, 3, 4})
  217. _, err := vm.RunString(`
  218. if (!s.hasOwnProperty("length")) {
  219. throw new Error("hasOwnProperty() returned false");
  220. }
  221. let desc = Object.getOwnPropertyDescriptor(s, "length");
  222. if (desc.value !== 3 || !desc.writable || desc.enumerable || desc.configurable) {
  223. throw new Error("incorrect property descriptor: " + JSON.stringify(desc));
  224. }
  225. `)
  226. if err != nil {
  227. t.Fatal(err)
  228. }
  229. }
  230. func TestGoSliceSort(t *testing.T) {
  231. vm := New()
  232. s := []interface{}{4, 2, 3}
  233. vm.Set("s", &s)
  234. _, err := vm.RunString(`s.sort()`)
  235. if err != nil {
  236. t.Fatal(err)
  237. }
  238. if len(s) != 3 {
  239. t.Fatalf("len: %d", len(s))
  240. }
  241. if s[0] != 2 || s[1] != 3 || s[2] != 4 {
  242. t.Fatalf("val: %v", s)
  243. }
  244. }
  245. func TestGoSliceToString(t *testing.T) {
  246. vm := New()
  247. s := []interface{}{4, 2, 3}
  248. vm.Set("s", &s)
  249. res, err := vm.RunString("`${s}`")
  250. if err != nil {
  251. t.Fatal(err)
  252. }
  253. if exp := res.Export(); exp != "4,2,3" {
  254. t.Fatal(exp)
  255. }
  256. }
  257. func TestGoSliceExternalLenUpdate(t *testing.T) {
  258. data := &[]interface{}{1}
  259. vm := New()
  260. vm.Set("data", data)
  261. vm.Set("append", func(a *[]interface{}, v int) {
  262. if a != data {
  263. panic(vm.NewTypeError("a != data"))
  264. }
  265. *a = append(*a, v)
  266. })
  267. vm.testScriptWithTestLib(`
  268. assert.sameValue(data.length, 1);
  269. // modify with js
  270. data.push(1);
  271. assert.sameValue(data.length, 2);
  272. // modify with go
  273. append(data, 2);
  274. assert.sameValue(data.length, 3);
  275. `, _undefined, t)
  276. }