object_test.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. package goja
  2. import "testing"
  3. func TestArray1(t *testing.T) {
  4. r := &Runtime{}
  5. a := r.newArray(nil)
  6. a.setOwnIdx(valueInt(0), asciiString("test"), true)
  7. if l := a.getStr("length", nil).ToInteger(); l != 1 {
  8. t.Fatalf("Unexpected length: %d", l)
  9. }
  10. }
  11. func TestDefineProperty(t *testing.T) {
  12. r := New()
  13. o := r.NewObject()
  14. err := o.DefineDataProperty("data", r.ToValue(42), FLAG_TRUE, FLAG_TRUE, FLAG_TRUE)
  15. if err != nil {
  16. t.Fatal(err)
  17. }
  18. err = o.DefineAccessorProperty("accessor_ro", r.ToValue(func() int {
  19. return 1
  20. }), nil, FLAG_TRUE, FLAG_TRUE)
  21. if err != nil {
  22. t.Fatal(err)
  23. }
  24. err = o.DefineAccessorProperty("accessor_rw",
  25. r.ToValue(func(call FunctionCall) Value {
  26. return o.Get("__hidden")
  27. }),
  28. r.ToValue(func(call FunctionCall) (ret Value) {
  29. o.Set("__hidden", call.Argument(0))
  30. return
  31. }),
  32. FLAG_TRUE, FLAG_TRUE)
  33. if err != nil {
  34. t.Fatal(err)
  35. }
  36. if v := o.Get("accessor_ro"); v.ToInteger() != 1 {
  37. t.Fatalf("Unexpected accessor value: %v", v)
  38. }
  39. err = o.Set("accessor_ro", r.ToValue(2))
  40. if err == nil {
  41. t.Fatal("Expected an error")
  42. }
  43. if ex, ok := err.(*Exception); ok {
  44. if msg := ex.Error(); msg != "TypeError: Cannot assign to read only property 'accessor_ro'" {
  45. t.Fatalf("Unexpected error: '%s'", msg)
  46. }
  47. } else {
  48. t.Fatalf("Unexected error type: %T", err)
  49. }
  50. err = o.Set("accessor_rw", 42)
  51. if err != nil {
  52. t.Fatal(err)
  53. }
  54. if v := o.Get("accessor_rw"); v.ToInteger() != 42 {
  55. t.Fatalf("Unexpected value: %v", v)
  56. }
  57. }
  58. func TestPropertyOrder(t *testing.T) {
  59. const SCRIPT = `
  60. var o = {};
  61. var sym1 = Symbol(1);
  62. var sym2 = Symbol(2);
  63. o[sym2] = 1;
  64. o[4294967294] = 1;
  65. o[2] = 1;
  66. o[1] = 1;
  67. o[0] = 1;
  68. o["02"] = 1;
  69. o[4294967295] = 1;
  70. o["01"] = 1;
  71. o["00"] = 1;
  72. o[sym1] = 1;
  73. var expected = ["0", "1", "2", "4294967294", "02", "4294967295", "01", "00", sym2, sym1];
  74. var actual = Reflect.ownKeys(o);
  75. if (actual.length !== expected.length) {
  76. throw new Error("Unexpected length: "+actual.length);
  77. }
  78. for (var i = 0; i < actual.length; i++) {
  79. if (actual[i] !== expected[i]) {
  80. throw new Error("Unexpected list: " + actual);
  81. }
  82. }
  83. `
  84. testScript1(SCRIPT, _undefined, t)
  85. }
  86. func TestDefinePropertiesSymbol(t *testing.T) {
  87. const SCRIPT = `
  88. var desc = {};
  89. desc[Symbol.toStringTag] = {value: "Test"};
  90. var o = {};
  91. Object.defineProperties(o, desc);
  92. o[Symbol.toStringTag] === "Test";
  93. `
  94. testScript1(SCRIPT, valueTrue, t)
  95. }
  96. func TestObjectAssign(t *testing.T) {
  97. const SCRIPT = `
  98. assert.sameValue(Object.assign({ b: 1 }, { get a() {
  99. Object.defineProperty(this, "b", {
  100. value: 3,
  101. enumerable: false
  102. });
  103. }, b: 2 }).b, 1, "#1");
  104. assert.sameValue(Object.assign({ b: 1 }, { get a() {
  105. delete this.b;
  106. }, b: 2 }).b, 1, "#2");
  107. `
  108. testScript1(TESTLIB+SCRIPT, _undefined, t)
  109. }
  110. func BenchmarkPut(b *testing.B) {
  111. v := &Object{}
  112. o := &baseObject{
  113. val: v,
  114. extensible: true,
  115. }
  116. v.self = o
  117. o.init()
  118. var key Value = asciiString("test")
  119. var val Value = valueInt(123)
  120. for i := 0; i < b.N; i++ {
  121. v.setOwn(key, val, false)
  122. }
  123. }
  124. func BenchmarkPutStr(b *testing.B) {
  125. v := &Object{}
  126. o := &baseObject{
  127. val: v,
  128. extensible: true,
  129. }
  130. o.init()
  131. v.self = o
  132. var val Value = valueInt(123)
  133. for i := 0; i < b.N; i++ {
  134. o.setOwnStr("test", val, false)
  135. }
  136. }
  137. func BenchmarkGet(b *testing.B) {
  138. v := &Object{}
  139. o := &baseObject{
  140. val: v,
  141. extensible: true,
  142. }
  143. o.init()
  144. v.self = o
  145. var n Value = asciiString("test")
  146. for i := 0; i < b.N; i++ {
  147. v.get(n, nil)
  148. }
  149. }
  150. func BenchmarkGetStr(b *testing.B) {
  151. v := &Object{}
  152. o := &baseObject{
  153. val: v,
  154. extensible: true,
  155. }
  156. v.self = o
  157. o.init()
  158. for i := 0; i < b.N; i++ {
  159. o.getStr("test", nil)
  160. }
  161. }
  162. func _toString(v Value) string {
  163. switch v := v.(type) {
  164. case asciiString:
  165. return string(v)
  166. default:
  167. return ""
  168. }
  169. }
  170. func BenchmarkToString1(b *testing.B) {
  171. v := asciiString("test")
  172. for i := 0; i < b.N; i++ {
  173. v.toString()
  174. }
  175. }
  176. func BenchmarkToString2(b *testing.B) {
  177. v := asciiString("test")
  178. for i := 0; i < b.N; i++ {
  179. _toString(v)
  180. }
  181. }
  182. func BenchmarkConv(b *testing.B) {
  183. count := int64(0)
  184. for i := 0; i < b.N; i++ {
  185. count += valueInt(123).ToInteger()
  186. }
  187. if count == 0 {
  188. b.Fatal("zero")
  189. }
  190. }
  191. func BenchmarkArrayGetStr(b *testing.B) {
  192. b.StopTimer()
  193. r := New()
  194. v := &Object{runtime: r}
  195. a := &arrayObject{
  196. baseObject: baseObject{
  197. val: v,
  198. extensible: true,
  199. },
  200. }
  201. v.self = a
  202. a.init()
  203. v.setOwn(valueInt(0), asciiString("test"), false)
  204. b.StartTimer()
  205. for i := 0; i < b.N; i++ {
  206. a.getStr("0", nil)
  207. }
  208. }
  209. func BenchmarkArrayGet(b *testing.B) {
  210. b.StopTimer()
  211. r := New()
  212. v := &Object{runtime: r}
  213. a := &arrayObject{
  214. baseObject: baseObject{
  215. val: v,
  216. extensible: true,
  217. },
  218. }
  219. v.self = a
  220. a.init()
  221. var idx Value = valueInt(0)
  222. v.setOwn(idx, asciiString("test"), false)
  223. b.StartTimer()
  224. for i := 0; i < b.N; i++ {
  225. v.get(idx, nil)
  226. }
  227. }
  228. func BenchmarkArrayPut(b *testing.B) {
  229. b.StopTimer()
  230. r := New()
  231. v := &Object{runtime: r}
  232. a := &arrayObject{
  233. baseObject: baseObject{
  234. val: v,
  235. extensible: true,
  236. },
  237. }
  238. v.self = a
  239. a.init()
  240. var idx Value = valueInt(0)
  241. var val Value = asciiString("test")
  242. b.StartTimer()
  243. for i := 0; i < b.N; i++ {
  244. v.setOwn(idx, val, false)
  245. }
  246. }
  247. func BenchmarkToUTF8String(b *testing.B) {
  248. var s valueString = asciiString("test")
  249. for i := 0; i < b.N; i++ {
  250. _ = s.String()
  251. }
  252. }
  253. func BenchmarkAdd(b *testing.B) {
  254. var x, y Value
  255. x = valueInt(2)
  256. y = valueInt(2)
  257. for i := 0; i < b.N; i++ {
  258. if xi, ok := x.(valueInt); ok {
  259. if yi, ok := y.(valueInt); ok {
  260. x = xi + yi
  261. }
  262. }
  263. }
  264. }
  265. func BenchmarkAddString(b *testing.B) {
  266. var x, y Value
  267. tst := asciiString("22")
  268. x = asciiString("2")
  269. y = asciiString("2")
  270. for i := 0; i < b.N; i++ {
  271. var z Value
  272. if xi, ok := x.(valueString); ok {
  273. if yi, ok := y.(valueString); ok {
  274. z = xi.concat(yi)
  275. }
  276. }
  277. if !z.StrictEquals(tst) {
  278. b.Fatalf("Unexpected result %v", x)
  279. }
  280. }
  281. }