runtime_test.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917
  1. package goja
  2. import (
  3. "errors"
  4. "fmt"
  5. "reflect"
  6. "testing"
  7. "time"
  8. )
  9. func TestGlobalObjectProto(t *testing.T) {
  10. const SCRIPT = `
  11. this instanceof Object
  12. `
  13. testScript1(SCRIPT, valueTrue, t)
  14. }
  15. func TestArrayProtoProp(t *testing.T) {
  16. const SCRIPT = `
  17. Object.defineProperty(Array.prototype, '0', {value: 42, configurable: true, writable: false})
  18. var a = []
  19. a[0] = 1
  20. a[0]
  21. `
  22. testScript1(SCRIPT, valueInt(42), t)
  23. }
  24. func TestArrayDelete(t *testing.T) {
  25. const SCRIPT = `
  26. var a = [1, 2];
  27. var deleted = delete a[0];
  28. var undef = a[0] === undefined;
  29. var len = a.length;
  30. deleted && undef && len === 2;
  31. `
  32. testScript1(SCRIPT, valueTrue, t)
  33. }
  34. func TestArrayDeleteNonexisting(t *testing.T) {
  35. const SCRIPT = `
  36. Array.prototype[0] = 42;
  37. var a = [];
  38. delete a[0] && a[0] === 42;
  39. `
  40. testScript1(SCRIPT, valueTrue, t)
  41. }
  42. func TestArraySetLength(t *testing.T) {
  43. const SCRIPT = `
  44. var a = [1, 2];
  45. var assert0 = a.length == 2;
  46. a.length = "1";
  47. a.length = 1.0;
  48. a.length = 1;
  49. var assert1 = a.length == 1;
  50. a.length = 2;
  51. var assert2 = a.length == 2;
  52. assert0 && assert1 && assert2 && a[1] === undefined;
  53. `
  54. testScript1(SCRIPT, valueTrue, t)
  55. }
  56. func TestUnicodeString(t *testing.T) {
  57. const SCRIPT = `
  58. var s = "Тест";
  59. s.length === 4 && s[1] === "е";
  60. `
  61. testScript1(SCRIPT, valueTrue, t)
  62. }
  63. func TestArrayReverseNonOptimisable(t *testing.T) {
  64. const SCRIPT = `
  65. var a = [];
  66. Object.defineProperty(a, "0", {get: function() {return 42}, set: function(v) {Object.defineProperty(a, "0", {value: v + 1, writable: true, configurable: true})}, configurable: true})
  67. a[1] = 43;
  68. a.reverse();
  69. a.length === 2 && a[0] === 44 && a[1] === 42;
  70. `
  71. testScript1(SCRIPT, valueTrue, t)
  72. }
  73. func TestArrayPushNonOptimisable(t *testing.T) {
  74. const SCRIPT = `
  75. Object.defineProperty(Object.prototype, "0", {value: 42});
  76. var a = [];
  77. var thrown = false;
  78. try {
  79. a.push(1);
  80. } catch (e) {
  81. thrown = e instanceof TypeError;
  82. }
  83. thrown;
  84. `
  85. testScript1(SCRIPT, valueTrue, t)
  86. }
  87. func TestArraySetLengthWithPropItems(t *testing.T) {
  88. const SCRIPT = `
  89. var a = [1,2,3,4];
  90. var thrown = false;
  91. Object.defineProperty(a, "2", {value: 42, configurable: false, writable: false});
  92. try {
  93. Object.defineProperty(a, "length", {value: 0, writable: false});
  94. } catch (e) {
  95. thrown = e instanceof TypeError;
  96. }
  97. thrown && a.length === 3;
  98. `
  99. testScript1(SCRIPT, valueTrue, t)
  100. }
  101. func Test2TierHierarchyProp(t *testing.T) {
  102. const SCRIPT = `
  103. var a = {};
  104. Object.defineProperty(a, "test", {
  105. value: 42,
  106. writable: false,
  107. enumerable: false,
  108. configurable: true
  109. });
  110. var b = Object.create(a);
  111. var c = Object.create(b);
  112. c.test = 43;
  113. c.test === 42 && !b.hasOwnProperty("test");
  114. `
  115. testScript1(SCRIPT, valueTrue, t)
  116. }
  117. func TestConstStringIter(t *testing.T) {
  118. const SCRIPT = `
  119. var count = 0;
  120. for (var i in "1234") {
  121. for (var j in "1234567") {
  122. count++
  123. }
  124. }
  125. count;
  126. `
  127. testScript1(SCRIPT, intToValue(28), t)
  128. }
  129. func TestUnicodeConcat(t *testing.T) {
  130. const SCRIPT = `
  131. var s = "тест";
  132. var s1 = "test";
  133. var s2 = "абвгд";
  134. s.concat(s1) === "тестtest" && s.concat(s1, s2) === "тестtestабвгд" && s1.concat(s, s2) === "testтестабвгд"
  135. && s.concat(s2) === "тестабвгд";
  136. `
  137. testScript1(SCRIPT, valueTrue, t)
  138. }
  139. func TestIndexOf(t *testing.T) {
  140. const SCRIPT = `
  141. "abc".indexOf("", 4)
  142. `
  143. testScript1(SCRIPT, intToValue(3), t)
  144. }
  145. func TestUnicodeIndexOf(t *testing.T) {
  146. const SCRIPT = `
  147. "абвгд".indexOf("вг", 1)
  148. `
  149. testScript1(SCRIPT, intToValue(2), t)
  150. }
  151. func TestLastIndexOf(t *testing.T) {
  152. const SCRIPT = `
  153. "abcabab".lastIndexOf("ab", 3)
  154. `
  155. testScript1(SCRIPT, intToValue(3), t)
  156. }
  157. func TestUnicodeLastIndexOf(t *testing.T) {
  158. const SCRIPT = `
  159. "абвабаб".lastIndexOf("аб", 3)
  160. `
  161. testScript1(SCRIPT, intToValue(3), t)
  162. }
  163. func TestUnicodeLastIndexOf1(t *testing.T) {
  164. const SCRIPT = `
  165. "abꞐcde".lastIndexOf("cd");
  166. `
  167. testScript1(SCRIPT, intToValue(3), t)
  168. }
  169. func TestNumber(t *testing.T) {
  170. const SCRIPT = `
  171. (new Number(100111122133144155)).toString()
  172. `
  173. testScript1(SCRIPT, asciiString("100111122133144160"), t)
  174. }
  175. func TestFractionalNumberToStringRadix(t *testing.T) {
  176. const SCRIPT = `
  177. (new Number(123.456)).toString(36)
  178. `
  179. testScript1(SCRIPT, asciiString("3f.gez4w97ry"), t)
  180. }
  181. func TestSetFunc(t *testing.T) {
  182. const SCRIPT = `
  183. sum(40, 2);
  184. `
  185. r := New()
  186. r.Set("sum", func(call FunctionCall) Value {
  187. return r.ToValue(call.Argument(0).ToInteger() + call.Argument(1).ToInteger())
  188. })
  189. v, err := r.RunString(SCRIPT)
  190. if err != nil {
  191. t.Fatal(err)
  192. }
  193. if i := v.ToInteger(); i != 42 {
  194. t.Fatalf("Expected 42, got: %d", i)
  195. }
  196. }
  197. func TestObjectGetSet(t *testing.T) {
  198. const SCRIPT = `
  199. input.test++;
  200. input;
  201. `
  202. r := New()
  203. o := r.NewObject()
  204. o.Set("test", 42)
  205. r.Set("input", o)
  206. v, err := r.RunString(SCRIPT)
  207. if err != nil {
  208. t.Fatal(err)
  209. }
  210. if o1, ok := v.(*Object); ok {
  211. if v1 := o1.Get("test"); v1.Export() != int64(43) {
  212. t.Fatalf("Unexpected test value: %v (%T)", v1, v1.Export())
  213. }
  214. }
  215. }
  216. func TestThrowFromNativeFunc(t *testing.T) {
  217. const SCRIPT = `
  218. var thrown;
  219. try {
  220. f();
  221. } catch (e) {
  222. thrown = e;
  223. }
  224. thrown;
  225. `
  226. r := New()
  227. r.Set("f", func(call FunctionCall) Value {
  228. panic(r.ToValue("testError"))
  229. })
  230. v, err := r.RunString(SCRIPT)
  231. if err != nil {
  232. t.Fatal(err)
  233. }
  234. if !v.Equals(asciiString("testError")) {
  235. t.Fatalf("Unexpected result: %v", v)
  236. }
  237. }
  238. func TestSetGoFunc(t *testing.T) {
  239. const SCRIPT = `
  240. f(40, 2)
  241. `
  242. r := New()
  243. r.Set("f", func(a, b int) int {
  244. return a + b
  245. })
  246. v, err := r.RunString(SCRIPT)
  247. if err != nil {
  248. t.Fatal(err)
  249. }
  250. if v.ToInteger() != 42 {
  251. t.Fatalf("Unexpected result: %v", v)
  252. }
  253. }
  254. func TestArgsKeys(t *testing.T) {
  255. const SCRIPT = `
  256. function testArgs2(x, y, z) {
  257. // Properties of the arguments object are enumerable.
  258. return Object.keys(arguments);
  259. }
  260. testArgs2(1,2).length
  261. `
  262. testScript1(SCRIPT, intToValue(2), t)
  263. }
  264. func TestIPowOverflow(t *testing.T) {
  265. const SCRIPT = `
  266. Math.pow(65536, 6)
  267. `
  268. testScript1(SCRIPT, floatToValue(7.922816251426434e+28), t)
  269. }
  270. func TestIPowZero(t *testing.T) {
  271. const SCRIPT = `
  272. Math.pow(0, 0)
  273. `
  274. testScript1(SCRIPT, intToValue(1), t)
  275. }
  276. func TestInterrupt(t *testing.T) {
  277. const SCRIPT = `
  278. var i = 0;
  279. for (;;) {
  280. i++;
  281. }
  282. `
  283. vm := New()
  284. time.AfterFunc(200*time.Millisecond, func() {
  285. vm.Interrupt("halt")
  286. })
  287. _, err := vm.RunString(SCRIPT)
  288. if err == nil {
  289. t.Fatal("Err is nil")
  290. }
  291. }
  292. func TestRuntime_ExportToSlice(t *testing.T) {
  293. const SCRIPT = `
  294. var a = [1, 2, 3];
  295. a;
  296. `
  297. vm := New()
  298. v, err := vm.RunString(SCRIPT)
  299. if err != nil {
  300. t.Fatal(err)
  301. }
  302. var a []string
  303. err = vm.ExportTo(v, &a)
  304. if err != nil {
  305. t.Fatal(err)
  306. }
  307. if l := len(a); l != 3 {
  308. t.Fatalf("Unexpected len: %d", l)
  309. }
  310. if a[0] != "1" || a[1] != "2" || a[2] != "3" {
  311. t.Fatalf("Unexpected value: %+v", a)
  312. }
  313. }
  314. func TestRuntime_ExportToMap(t *testing.T) {
  315. const SCRIPT = `
  316. var m = {
  317. "0": 1,
  318. "1": 2,
  319. "2": 3,
  320. }
  321. m;
  322. `
  323. vm := New()
  324. v, err := vm.RunString(SCRIPT)
  325. if err != nil {
  326. t.Fatal(err)
  327. }
  328. var m map[int]string
  329. err = vm.ExportTo(v, &m)
  330. if err != nil {
  331. t.Fatal(err)
  332. }
  333. if l := len(m); l != 3 {
  334. t.Fatalf("Unexpected len: %d", l)
  335. }
  336. if m[0] != "1" || m[1] != "2" || m[2] != "3" {
  337. t.Fatalf("Unexpected value: %+v", m)
  338. }
  339. }
  340. func TestRuntime_ExportToMap1(t *testing.T) {
  341. const SCRIPT = `
  342. var m = {
  343. "0": 1,
  344. "1": 2,
  345. "2": 3,
  346. }
  347. m;
  348. `
  349. vm := New()
  350. v, err := vm.RunString(SCRIPT)
  351. if err != nil {
  352. t.Fatal(err)
  353. }
  354. var m map[string]string
  355. err = vm.ExportTo(v, &m)
  356. if err != nil {
  357. t.Fatal(err)
  358. }
  359. if l := len(m); l != 3 {
  360. t.Fatalf("Unexpected len: %d", l)
  361. }
  362. if m["0"] != "1" || m["1"] != "2" || m["2"] != "3" {
  363. t.Fatalf("Unexpected value: %+v", m)
  364. }
  365. }
  366. func TestRuntime_ExportToStruct(t *testing.T) {
  367. const SCRIPT = `
  368. var m = {
  369. Test: 1,
  370. }
  371. m;
  372. `
  373. vm := New()
  374. v, err := vm.RunString(SCRIPT)
  375. if err != nil {
  376. t.Fatal(err)
  377. }
  378. var o testGoReflectMethod_O
  379. err = vm.ExportTo(v, &o)
  380. if err != nil {
  381. t.Fatal(err)
  382. }
  383. if o.Test != "1" {
  384. t.Fatalf("Unexpected value: '%s'", o.Test)
  385. }
  386. }
  387. func TestRuntime_ExportToFunc(t *testing.T) {
  388. const SCRIPT = `
  389. function f(param) {
  390. return +param + 2;
  391. }
  392. `
  393. vm := New()
  394. _, err := vm.RunString(SCRIPT)
  395. if err != nil {
  396. t.Fatal(err)
  397. }
  398. var fn func(string) string
  399. vm.ExportTo(vm.Get("f"), &fn)
  400. if res := fn("40"); res != "42" {
  401. t.Fatalf("Unexpected value: %q", res)
  402. }
  403. }
  404. func TestRuntime_ExportToFuncThrow(t *testing.T) {
  405. const SCRIPT = `
  406. function f(param) {
  407. throw new Error("testing");
  408. }
  409. `
  410. vm := New()
  411. _, err := vm.RunString(SCRIPT)
  412. if err != nil {
  413. t.Fatal(err)
  414. }
  415. var fn func(string) (string, error)
  416. err = vm.ExportTo(vm.Get("f"), &fn)
  417. if err != nil {
  418. t.Fatal(err)
  419. }
  420. if _, err := fn("40"); err != nil {
  421. if ex, ok := err.(*Exception); ok {
  422. if msg := ex.Error(); msg != "Error: testing at f (<eval>:3:9(4))" {
  423. t.Fatalf("Msg: %q", msg)
  424. }
  425. } else {
  426. t.Fatalf("Error is not *Exception (%T): %v", err, err)
  427. }
  428. } else {
  429. t.Fatal("Expected error")
  430. }
  431. }
  432. func TestRuntime_ExportToFuncFail(t *testing.T) {
  433. const SCRIPT = `
  434. function f(param) {
  435. return +param + 2;
  436. }
  437. `
  438. type T struct {
  439. Field1 int
  440. }
  441. var fn func(string) (T, error)
  442. vm := New()
  443. _, err := vm.RunString(SCRIPT)
  444. if err != nil {
  445. t.Fatal(err)
  446. }
  447. err = vm.ExportTo(vm.Get("f"), &fn)
  448. if err != nil {
  449. t.Fatal(err)
  450. }
  451. if _, err := fn("40"); err == nil {
  452. t.Fatal("Expected error")
  453. }
  454. }
  455. func TestRuntime_ExportToCallable(t *testing.T) {
  456. const SCRIPT = `
  457. function f(param) {
  458. return +param + 2;
  459. }
  460. `
  461. vm := New()
  462. _, err := vm.RunString(SCRIPT)
  463. if err != nil {
  464. t.Fatal(err)
  465. }
  466. var c Callable
  467. err = vm.ExportTo(vm.Get("f"), &c)
  468. if err != nil {
  469. t.Fatal(err)
  470. }
  471. res, err := c(Undefined(), vm.ToValue("40"))
  472. if err != nil {
  473. t.Fatal(err)
  474. } else if !res.StrictEquals(vm.ToValue(42)) {
  475. t.Fatalf("Unexpected value: %v", res)
  476. }
  477. }
  478. func TestRuntime_ExportToObject(t *testing.T) {
  479. const SCRIPT = `
  480. var o = {"test": 42};
  481. o;
  482. `
  483. vm := New()
  484. _, err := vm.RunString(SCRIPT)
  485. if err != nil {
  486. t.Fatal(err)
  487. }
  488. var o *Object
  489. err = vm.ExportTo(vm.Get("o"), &o)
  490. if err != nil {
  491. t.Fatal(err)
  492. }
  493. if v := o.Get("test"); !v.StrictEquals(vm.ToValue(42)) {
  494. t.Fatalf("Unexpected value: %v", v)
  495. }
  496. }
  497. func TestGoFuncError(t *testing.T) {
  498. const SCRIPT = `
  499. try {
  500. f();
  501. } catch (e) {
  502. if (!(e instanceof GoError)) {
  503. throw(e);
  504. }
  505. if (e.value.Error() !== "Test") {
  506. throw("Unexpected value: " + e.value.Error());
  507. }
  508. }
  509. `
  510. f := func() error {
  511. return errors.New("Test")
  512. }
  513. vm := New()
  514. vm.Set("f", f)
  515. _, err := vm.RunString(SCRIPT)
  516. if err != nil {
  517. t.Fatal(err)
  518. }
  519. }
  520. func TestToValueNil(t *testing.T) {
  521. type T struct{}
  522. var a *T
  523. vm := New()
  524. if v := vm.ToValue(a); !IsNull(v) {
  525. t.Fatalf("Expected null, got: %v", v)
  526. }
  527. }
  528. func TestJSONEscape(t *testing.T) {
  529. const SCRIPT = `
  530. var a = "\\+1";
  531. JSON.stringify(a);
  532. `
  533. testScript1(SCRIPT, asciiString(`"\\+1"`), t)
  534. }
  535. func TestJSONObjectInArray(t *testing.T) {
  536. const SCRIPT = `
  537. var a = "[{\"a\":1},{\"a\":2}]";
  538. JSON.stringify(JSON.parse(a)) == a;
  539. `
  540. testScript1(SCRIPT, valueTrue, t)
  541. }
  542. func TestJSONQuirkyNumbers(t *testing.T) {
  543. const SCRIPT = `
  544. var s;
  545. s = JSON.stringify(NaN);
  546. if (s != "null") {
  547. throw new Error("NaN: " + s);
  548. }
  549. s = JSON.stringify(Infinity);
  550. if (s != "null") {
  551. throw new Error("Infinity: " + s);
  552. }
  553. s = JSON.stringify(-Infinity);
  554. if (s != "null") {
  555. throw new Error("-Infinity: " + s);
  556. }
  557. `
  558. testScript1(SCRIPT, _undefined, t)
  559. }
  560. func TestJSONNil(t *testing.T) {
  561. const SCRIPT = `
  562. JSON.stringify(i);
  563. `
  564. vm := New()
  565. var i interface{}
  566. vm.Set("i", i)
  567. ret, err := vm.RunString(SCRIPT)
  568. if err != nil {
  569. t.Fatal(err)
  570. }
  571. if ret.String() != "null" {
  572. t.Fatalf("Expected 'null', got: %v", ret)
  573. }
  574. }
  575. type customJsonEncodable struct{}
  576. func (*customJsonEncodable) JsonEncodable() interface{} {
  577. return "Test"
  578. }
  579. func TestJsonEncodable(t *testing.T) {
  580. var s customJsonEncodable
  581. vm := New()
  582. vm.Set("s", &s)
  583. ret, err := vm.RunString("JSON.stringify(s)")
  584. if err != nil {
  585. t.Fatal(err)
  586. }
  587. if !ret.StrictEquals(vm.ToValue("\"Test\"")) {
  588. t.Fatalf("Expected \"Test\", got: %v", ret)
  589. }
  590. }
  591. func TestSortComparatorReturnValues(t *testing.T) {
  592. const SCRIPT = `
  593. var a = [];
  594. for (var i = 0; i < 12; i++) {
  595. a[i] = i;
  596. }
  597. a.sort(function(x, y) { return y - x });
  598. for (var i = 0; i < 12; i++) {
  599. if (a[i] !== 11-i) {
  600. throw new Error("Value at index " + i + " is incorrect: " + a[i]);
  601. }
  602. }
  603. `
  604. testScript1(SCRIPT, _undefined, t)
  605. }
  606. func TestNilApplyArg(t *testing.T) {
  607. const SCRIPT = `
  608. (function x(a, b) {
  609. return a === undefined && b === 1;
  610. }).apply(this, [,1])
  611. `
  612. testScript1(SCRIPT, valueTrue, t)
  613. }
  614. func TestNilCallArg(t *testing.T) {
  615. const SCRIPT = `
  616. "use strict";
  617. function f(a) {
  618. return this === undefined && a === undefined;
  619. }
  620. `
  621. vm := New()
  622. prg := MustCompile("test.js", SCRIPT, false)
  623. vm.RunProgram(prg)
  624. if f, ok := AssertFunction(vm.Get("f")); ok {
  625. v, err := f(nil, nil)
  626. if err != nil {
  627. t.Fatal(err)
  628. }
  629. if !v.StrictEquals(valueTrue) {
  630. t.Fatalf("Unexpected result: %v", v)
  631. }
  632. }
  633. }
  634. func TestNullCallArg(t *testing.T) {
  635. const SCRIPT = `
  636. f(null);
  637. `
  638. vm := New()
  639. prg := MustCompile("test.js", SCRIPT, false)
  640. vm.Set("f", func(x *int) bool {
  641. return x == nil
  642. })
  643. v, err := vm.RunProgram(prg)
  644. if err != nil {
  645. t.Fatal(err)
  646. }
  647. if !v.StrictEquals(valueTrue) {
  648. t.Fatalf("Unexpected result: %v", v)
  649. }
  650. }
  651. func TestObjectKeys(t *testing.T) {
  652. const SCRIPT = `
  653. var o = { a: 1, b: 2, c: 3, d: 4 };
  654. o;
  655. `
  656. vm := New()
  657. prg := MustCompile("test.js", SCRIPT, false)
  658. res, err := vm.RunProgram(prg)
  659. if err != nil {
  660. t.Fatal(err)
  661. }
  662. if o, ok := res.(*Object); ok {
  663. keys := o.Keys()
  664. if !reflect.DeepEqual(keys, []string{"a", "b", "c", "d"}) {
  665. t.Fatalf("Unexpected keys: %v", keys)
  666. }
  667. }
  668. }
  669. func TestReflectCallExtraArgs(t *testing.T) {
  670. const SCRIPT = `
  671. f(41, "extra")
  672. `
  673. f := func(x int) int {
  674. return x + 1
  675. }
  676. vm := New()
  677. vm.Set("f", f)
  678. prg := MustCompile("test.js", SCRIPT, false)
  679. res, err := vm.RunProgram(prg)
  680. if err != nil {
  681. t.Fatal(err)
  682. }
  683. if !res.StrictEquals(intToValue(42)) {
  684. t.Fatalf("Unexpected result: %v", res)
  685. }
  686. }
  687. func TestReflectCallNotEnoughArgs(t *testing.T) {
  688. const SCRIPT = `
  689. f(42)
  690. `
  691. vm := New()
  692. f := func(x, y int, z *int, s string) (int, error) {
  693. if z != nil {
  694. return 0, fmt.Errorf("z is not nil")
  695. }
  696. if s != "" {
  697. return 0, fmt.Errorf("s is not \"\"")
  698. }
  699. return x + y, nil
  700. }
  701. vm.Set("f", f)
  702. prg := MustCompile("test.js", SCRIPT, false)
  703. res, err := vm.RunProgram(prg)
  704. if err != nil {
  705. t.Fatal(err)
  706. }
  707. if !res.StrictEquals(intToValue(42)) {
  708. t.Fatalf("Unexpected result: %v", res)
  709. }
  710. }
  711. func TestReflectCallVariadic(t *testing.T) {
  712. const SCRIPT = `
  713. var r = f("Hello %s, %d", "test", 42);
  714. if (r !== "Hello test, 42") {
  715. throw new Error("test 1 has failed: " + r);
  716. }
  717. r = f("Hello %s, %d", ["test", 42]);
  718. if (r !== "Hello test, 42") {
  719. throw new Error("test 2 has failed: " + r);
  720. }
  721. r = f("Hello %s, %s", "test");
  722. if (r !== "Hello test, %!s(MISSING)") {
  723. throw new Error("test 3 has failed: " + r);
  724. }
  725. r = f();
  726. if (r !== "") {
  727. throw new Error("test 4 has failed: " + r);
  728. }
  729. `
  730. vm := New()
  731. vm.Set("f", fmt.Sprintf)
  732. prg := MustCompile("test.js", SCRIPT, false)
  733. _, err := vm.RunProgram(prg)
  734. if err != nil {
  735. t.Fatal(err)
  736. }
  737. }
  738. /*
  739. func TestArrayConcatSparse(t *testing.T) {
  740. function foo(a,b,c)
  741. {
  742. arguments[0] = 1; arguments[1] = 'str'; arguments[2] = 2.1;
  743. if(1 === a && 'str' === b && 2.1 === c)
  744. return true;
  745. }
  746. const SCRIPT = `
  747. var a1 = [];
  748. var a2 = [];
  749. a1[500000] = 1;
  750. a2[1000000] = 2;
  751. var a3 = a1.concat(a2);
  752. a3.length === 1500002 && a3[500000] === 1 && a3[1500001] == 2;
  753. `
  754. testScript1(SCRIPT, valueTrue, t)
  755. }
  756. */