object_test.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  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 BenchmarkPut(b *testing.B) {
  87. v := &Object{}
  88. o := &baseObject{
  89. val: v,
  90. extensible: true,
  91. }
  92. v.self = o
  93. o.init()
  94. var key Value = asciiString("test")
  95. var val Value = valueInt(123)
  96. for i := 0; i < b.N; i++ {
  97. v.setOwn(key, val, false)
  98. }
  99. }
  100. func BenchmarkPutStr(b *testing.B) {
  101. v := &Object{}
  102. o := &baseObject{
  103. val: v,
  104. extensible: true,
  105. }
  106. o.init()
  107. v.self = o
  108. var val Value = valueInt(123)
  109. for i := 0; i < b.N; i++ {
  110. o.setOwnStr("test", val, false)
  111. }
  112. }
  113. func BenchmarkGet(b *testing.B) {
  114. v := &Object{}
  115. o := &baseObject{
  116. val: v,
  117. extensible: true,
  118. }
  119. o.init()
  120. v.self = o
  121. var n Value = asciiString("test")
  122. for i := 0; i < b.N; i++ {
  123. v.get(n, nil)
  124. }
  125. }
  126. func BenchmarkGetStr(b *testing.B) {
  127. v := &Object{}
  128. o := &baseObject{
  129. val: v,
  130. extensible: true,
  131. }
  132. v.self = o
  133. o.init()
  134. for i := 0; i < b.N; i++ {
  135. o.getStr("test", nil)
  136. }
  137. }
  138. func _toString(v Value) string {
  139. switch v := v.(type) {
  140. case asciiString:
  141. return string(v)
  142. default:
  143. return ""
  144. }
  145. }
  146. func BenchmarkToString1(b *testing.B) {
  147. v := asciiString("test")
  148. for i := 0; i < b.N; i++ {
  149. v.toString()
  150. }
  151. }
  152. func BenchmarkToString2(b *testing.B) {
  153. v := asciiString("test")
  154. for i := 0; i < b.N; i++ {
  155. _toString(v)
  156. }
  157. }
  158. func BenchmarkConv(b *testing.B) {
  159. count := int64(0)
  160. for i := 0; i < b.N; i++ {
  161. count += valueInt(123).ToInteger()
  162. }
  163. if count == 0 {
  164. b.Fatal("zero")
  165. }
  166. }
  167. func BenchmarkArrayGetStr(b *testing.B) {
  168. b.StopTimer()
  169. r := New()
  170. v := &Object{runtime: r}
  171. a := &arrayObject{
  172. baseObject: baseObject{
  173. val: v,
  174. extensible: true,
  175. },
  176. }
  177. v.self = a
  178. a.init()
  179. v.setOwn(valueInt(0), asciiString("test"), false)
  180. b.StartTimer()
  181. for i := 0; i < b.N; i++ {
  182. a.getStr("0", nil)
  183. }
  184. }
  185. func BenchmarkArrayGet(b *testing.B) {
  186. b.StopTimer()
  187. r := New()
  188. v := &Object{runtime: r}
  189. a := &arrayObject{
  190. baseObject: baseObject{
  191. val: v,
  192. extensible: true,
  193. },
  194. }
  195. v.self = a
  196. a.init()
  197. var idx Value = valueInt(0)
  198. v.setOwn(idx, asciiString("test"), false)
  199. b.StartTimer()
  200. for i := 0; i < b.N; i++ {
  201. v.get(idx, nil)
  202. }
  203. }
  204. func BenchmarkArrayPut(b *testing.B) {
  205. b.StopTimer()
  206. r := New()
  207. v := &Object{runtime: r}
  208. a := &arrayObject{
  209. baseObject: baseObject{
  210. val: v,
  211. extensible: true,
  212. },
  213. }
  214. v.self = a
  215. a.init()
  216. var idx Value = valueInt(0)
  217. var val Value = asciiString("test")
  218. b.StartTimer()
  219. for i := 0; i < b.N; i++ {
  220. v.setOwn(idx, val, false)
  221. }
  222. }
  223. func BenchmarkToUTF8String(b *testing.B) {
  224. var s valueString = asciiString("test")
  225. for i := 0; i < b.N; i++ {
  226. _ = s.String()
  227. }
  228. }
  229. func BenchmarkAdd(b *testing.B) {
  230. var x, y Value
  231. x = valueInt(2)
  232. y = valueInt(2)
  233. for i := 0; i < b.N; i++ {
  234. if xi, ok := x.(valueInt); ok {
  235. if yi, ok := y.(valueInt); ok {
  236. x = xi + yi
  237. }
  238. }
  239. }
  240. }
  241. func BenchmarkAddString(b *testing.B) {
  242. var x, y Value
  243. tst := asciiString("22")
  244. x = asciiString("2")
  245. y = asciiString("2")
  246. for i := 0; i < b.N; i++ {
  247. var z Value
  248. if xi, ok := x.(valueString); ok {
  249. if yi, ok := y.(valueString); ok {
  250. z = xi.concat(yi)
  251. }
  252. }
  253. if !z.StrictEquals(tst) {
  254. b.Fatalf("Unexpected result %v", x)
  255. }
  256. }
  257. }