tc39_test.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. package goja
  2. import (
  3. "errors"
  4. "fmt"
  5. "gopkg.in/yaml.v2"
  6. "io/ioutil"
  7. "os"
  8. "path"
  9. "sort"
  10. "strings"
  11. "sync"
  12. "testing"
  13. "time"
  14. )
  15. const (
  16. tc39BASE = "testdata/test262"
  17. )
  18. var (
  19. invalidFormatError = errors.New("Invalid file format")
  20. ignorableTestError = newSymbol(stringEmpty)
  21. sabStub = MustCompile("sabStub.js", `
  22. Object.defineProperty(this, "SharedArrayBuffer", {
  23. get: function() {
  24. throw IgnorableTestError;
  25. }
  26. });`,
  27. false)
  28. )
  29. var (
  30. skipList = map[string]bool{
  31. "test/built-ins/Date/prototype/toISOString/15.9.5.43-0-8.js": true, // timezone
  32. "test/built-ins/Date/prototype/toISOString/15.9.5.43-0-9.js": true, // timezone
  33. "test/built-ins/Date/prototype/toISOString/15.9.5.43-0-10.js": true, // timezone
  34. // \u{xxxxx}
  35. "test/annexB/built-ins/escape/escape-above-astral.js": true,
  36. "test/built-ins/RegExp/prototype/source/value-u.js": true,
  37. // SharedArrayBuffer
  38. "test/built-ins/ArrayBuffer/prototype/slice/this-is-sharedarraybuffer.js": true,
  39. // class
  40. "test/language/statements/class/subclass/builtin-objects/Symbol/symbol-valid-as-extends-value.js": true,
  41. "test/language/statements/class/subclass/builtin-objects/Symbol/new-symbol-with-super-throws.js": true,
  42. "test/language/statements/class/subclass/builtin-objects/WeakSet/super-must-be-called.js": true,
  43. "test/language/statements/class/subclass/builtin-objects/WeakSet/regular-subclassing.js": true,
  44. "test/language/statements/class/subclass/builtin-objects/WeakMap/super-must-be-called.js": true,
  45. "test/language/statements/class/subclass/builtin-objects/WeakMap/regular-subclassing.js": true,
  46. "test/language/statements/class/subclass/builtin-objects/Map/super-must-be-called.js": true,
  47. "test/language/statements/class/subclass/builtin-objects/Map/regular-subclassing.js": true,
  48. "test/language/statements/class/subclass/builtin-objects/Set/super-must-be-called.js": true,
  49. "test/language/statements/class/subclass/builtin-objects/Set/regular-subclassing.js": true,
  50. "test/language/statements/class/subclass/builtin-objects/Object/replacing-prototype.js": true,
  51. "test/language/statements/class/subclass/builtin-objects/Object/regular-subclassing.js": true,
  52. "test/built-ins/Array/prototype/concat/Array.prototype.concat_non-array.js": true,
  53. "test/language/statements/class/subclass/builtin-objects/Array/length.js": true,
  54. "test/language/statements/class/subclass/builtin-objects/TypedArray/super-must-be-called.js": true,
  55. "test/language/statements/class/subclass/builtin-objects/TypedArray/regular-subclassing.js": true,
  56. "test/language/statements/class/subclass/builtin-objects/DataView/super-must-be-called.js": true,
  57. "test/language/statements/class/subclass/builtin-objects/DataView/regular-subclassing.js": true,
  58. "test/language/statements/class/subclass/builtin-objects/String/super-must-be-called.js": true,
  59. "test/language/statements/class/subclass/builtin-objects/String/regular-subclassing.js": true,
  60. "test/language/statements/class/subclass/builtin-objects/String/length.js": true,
  61. "test/language/statements/class/subclass/builtin-objects/Date/super-must-be-called.js": true,
  62. "test/language/statements/class/subclass/builtin-objects/Date/regular-subclassing.js": true,
  63. "test/language/statements/class/subclass/builtin-objects/Number/super-must-be-called.js": true,
  64. "test/language/statements/class/subclass/builtin-objects/Number/regular-subclassing.js": true,
  65. "test/language/statements/class/subclass/builtin-objects/Function/super-must-be-called.js": true,
  66. "test/language/statements/class/subclass/builtin-objects/Function/regular-subclassing.js": true,
  67. "test/language/statements/class/subclass/builtin-objects/Function/instance-name.js": true,
  68. "test/language/statements/class/subclass/builtin-objects/Function/instance-length.js": true,
  69. "test/language/statements/class/subclass/builtin-objects/Boolean/super-must-be-called.js": true,
  70. "test/language/statements/class/subclass/builtin-objects/Boolean/regular-subclassing.js": true,
  71. "test/language/statements/class/subclass/builtin-objects/NativeError/URIError-super.js": true,
  72. "test/language/statements/class/subclass/builtin-objects/NativeError/URIError-name.js": true,
  73. "test/language/statements/class/subclass/builtin-objects/NativeError/URIError-message.js": true,
  74. "test/language/statements/class/subclass/builtin-objects/NativeError/TypeError-super.js": true,
  75. "test/language/statements/class/subclass/builtin-objects/NativeError/TypeError-name.js": true,
  76. "test/language/statements/class/subclass/builtin-objects/NativeError/TypeError-message.js": true,
  77. "test/language/statements/class/subclass/builtin-objects/NativeError/SyntaxError-super.js": true,
  78. "test/language/statements/class/subclass/builtin-objects/NativeError/SyntaxError-name.js": true,
  79. "test/language/statements/class/subclass/builtin-objects/NativeError/SyntaxError-message.js": true,
  80. "test/language/statements/class/subclass/builtin-objects/NativeError/ReferenceError-super.js": true,
  81. "test/language/statements/class/subclass/builtin-objects/NativeError/ReferenceError-name.js": true,
  82. "test/language/statements/class/subclass/builtin-objects/NativeError/ReferenceError-message.js": true,
  83. "test/language/statements/class/subclass/builtin-objects/NativeError/RangeError-super.js": true,
  84. "test/language/statements/class/subclass/builtin-objects/NativeError/RangeError-name.js": true,
  85. "test/language/statements/class/subclass/builtin-objects/NativeError/RangeError-message.js": true,
  86. "test/language/statements/class/subclass/builtin-objects/NativeError/EvalError-super.js": true,
  87. "test/language/statements/class/subclass/builtin-objects/NativeError/EvalError-name.js": true,
  88. "test/language/statements/class/subclass/builtin-objects/NativeError/EvalError-message.js": true,
  89. "test/language/statements/class/subclass/builtin-objects/Error/super-must-be-called.js": true,
  90. "test/language/statements/class/subclass/builtin-objects/Error/regular-subclassing.js": true,
  91. "test/language/statements/class/subclass/builtin-objects/Error/message-property-assignment.js": true,
  92. "test/language/statements/class/subclass/builtin-objects/Array/super-must-be-called.js": true,
  93. "test/language/statements/class/subclass/builtin-objects/Array/regular-subclassing.js": true,
  94. "test/language/statements/class/subclass/builtin-objects/Array/contructor-calls-super-single-argument.js": true,
  95. "test/language/statements/class/subclass/builtin-objects/Array/contructor-calls-super-multiple-arguments.js": true,
  96. "test/language/statements/class/subclass/builtin-objects/ArrayBuffer/super-must-be-called.js": true,
  97. "test/language/statements/class/subclass/builtin-objects/ArrayBuffer/regular-subclassing.js": true,
  98. "test/built-ins/ArrayBuffer/isView/arg-is-typedarray-subclass-instance.js": true,
  99. "test/built-ins/ArrayBuffer/isView/arg-is-dataview-subclass-instance.js": true,
  100. "test/language/statements/class/subclass/builtin-objects/RegExp/super-must-be-called.js": true,
  101. "test/language/statements/class/subclass/builtin-objects/RegExp/regular-subclassing.js": true,
  102. "test/language/statements/class/subclass/builtin-objects/RegExp/lastIndex.js": true,
  103. // object literals
  104. "test/built-ins/Array/from/source-object-iterator-1.js": true,
  105. "test/built-ins/Array/from/source-object-iterator-2.js": true,
  106. "test/built-ins/TypedArray/prototype/fill/fill-values-conversion-once.js": true,
  107. "test/built-ins/TypedArrays/of/this-is-not-constructor.js": true,
  108. "test/built-ins/TypedArrays/of/argument-number-value-throws.js": true,
  109. "test/built-ins/TypedArrays/from/this-is-not-constructor.js": true,
  110. "test/built-ins/TypedArrays/from/set-value-abrupt-completion.js": true,
  111. "test/built-ins/TypedArrays/from/property-abrupt-completion.js": true,
  112. "test/built-ins/TypedArray/of/this-is-not-constructor.js": true,
  113. "test/built-ins/TypedArray/from/this-is-not-constructor.js": true,
  114. "test/built-ins/DataView/custom-proto-access-throws.js": true,
  115. "test/built-ins/DataView/custom-proto-access-throws-sab.js": true,
  116. // arrow-function
  117. "test/built-ins/Object/prototype/toString/proxy-function.js": true,
  118. // template strings
  119. "test/built-ins/String/raw/zero-literal-segments.js": true,
  120. "test/built-ins/String/raw/template-substitutions-are-appended-on-same-index.js": true,
  121. "test/built-ins/String/raw/special-characters.js": true,
  122. "test/built-ins/String/raw/return-the-string-value-from-template.js": true,
  123. // restricted unicode regexp syntax
  124. "test/built-ins/RegExp/unicode_restricted_quantifiable_assertion.js": true,
  125. "test/built-ins/RegExp/unicode_restricted_octal_escape.js": true,
  126. "test/built-ins/RegExp/unicode_restricted_incomple_quantifier.js": true,
  127. "test/built-ins/RegExp/unicode_restricted_identity_escape_x.js": true,
  128. "test/built-ins/RegExp/unicode_restricted_identity_escape_u.js": true,
  129. "test/built-ins/RegExp/unicode_restricted_identity_escape_c.js": true,
  130. "test/built-ins/RegExp/unicode_restricted_identity_escape_alpha.js": true,
  131. "test/built-ins/RegExp/unicode_restricted_identity_escape.js": true,
  132. "test/built-ins/RegExp/unicode_restricted_brackets.js": true,
  133. "test/built-ins/RegExp/unicode_restricted_character_class_escape.js": true,
  134. "test/annexB/built-ins/RegExp/prototype/compile/pattern-string-invalid-u.js": true,
  135. // Because goja parser works in UTF-8 it is not possible to pass strings containing invalid UTF-16 code points.
  136. // This is mitigated by escaping them as \uXXXX, however because of this the RegExp source becomes
  137. // `\uXXXX` instead of `<the actual UTF-16 code point of XXXX>`.
  138. // The resulting RegExp will work exactly the same, but it causes these two tests to fail.
  139. "test/annexB/built-ins/RegExp/RegExp-leading-escape-BMP.js": true,
  140. "test/annexB/built-ins/RegExp/RegExp-trailing-escape-BMP.js": true,
  141. // Promise
  142. "test/built-ins/Symbol/species/builtin-getter-name.js": true,
  143. }
  144. featuresBlackList = []string{
  145. "arrow-function",
  146. }
  147. es6WhiteList = map[string]bool{}
  148. es6IdWhiteList = []string{
  149. "8.1.2.1",
  150. "9.5",
  151. "12.9.3",
  152. "12.9.4",
  153. "19.1",
  154. "19.2",
  155. "19.3",
  156. "19.4",
  157. "19.5",
  158. "20.1",
  159. "20.2",
  160. "20.3",
  161. "21.1",
  162. "21.2",
  163. "22.1",
  164. "22.2",
  165. "23.1",
  166. "23.2",
  167. "23.3",
  168. "23.4",
  169. "24.1",
  170. "24.2",
  171. "24.3",
  172. "25.1.2",
  173. "26.1",
  174. "26.2",
  175. "B.2.1",
  176. "B.2.2",
  177. }
  178. esIdPrefixWhiteList = []string{
  179. "sec-array",
  180. "sec-%typedarray%",
  181. "sec-string",
  182. "sec-date",
  183. "sec-number",
  184. "sec-math",
  185. "sec-arraybuffer-length",
  186. "sec-arraybuffer",
  187. "sec-regexp",
  188. }
  189. )
  190. type tc39Test struct {
  191. name string
  192. f func(t *testing.T)
  193. }
  194. type tc39BenchmarkItem struct {
  195. name string
  196. duration time.Duration
  197. }
  198. type tc39BenchmarkData []tc39BenchmarkItem
  199. type tc39TestCtx struct {
  200. base string
  201. t *testing.T
  202. prgCache map[string]*Program
  203. prgCacheLock sync.Mutex
  204. enableBench bool
  205. benchmark tc39BenchmarkData
  206. benchLock sync.Mutex
  207. testQueue []tc39Test
  208. }
  209. type TC39MetaNegative struct {
  210. Phase, Type string
  211. }
  212. type tc39Meta struct {
  213. Negative TC39MetaNegative
  214. Includes []string
  215. Flags []string
  216. Features []string
  217. Es5id string
  218. Es6id string
  219. Esid string
  220. }
  221. func (m *tc39Meta) hasFlag(flag string) bool {
  222. for _, f := range m.Flags {
  223. if f == flag {
  224. return true
  225. }
  226. }
  227. return false
  228. }
  229. func parseTC39File(name string) (*tc39Meta, string, error) {
  230. f, err := os.Open(name)
  231. if err != nil {
  232. return nil, "", err
  233. }
  234. defer f.Close()
  235. b, err := ioutil.ReadAll(f)
  236. if err != nil {
  237. return nil, "", err
  238. }
  239. str := string(b)
  240. metaStart := strings.Index(str, "/*---")
  241. if metaStart == -1 {
  242. return nil, "", invalidFormatError
  243. } else {
  244. metaStart += 5
  245. }
  246. metaEnd := strings.Index(str, "---*/")
  247. if metaEnd == -1 || metaEnd <= metaStart {
  248. return nil, "", invalidFormatError
  249. }
  250. var meta tc39Meta
  251. err = yaml.Unmarshal([]byte(str[metaStart:metaEnd]), &meta)
  252. if err != nil {
  253. return nil, "", err
  254. }
  255. if meta.Negative.Type != "" && meta.Negative.Phase == "" {
  256. return nil, "", errors.New("negative type is set, but phase isn't")
  257. }
  258. return &meta, str, nil
  259. }
  260. func (*tc39TestCtx) detachArrayBuffer(call FunctionCall) Value {
  261. if obj, ok := call.Argument(0).(*Object); ok {
  262. if buf, ok := obj.self.(*arrayBufferObject); ok {
  263. buf.detach()
  264. return _undefined
  265. }
  266. }
  267. panic(typeError("detachArrayBuffer() is called with incompatible argument"))
  268. }
  269. func (*tc39TestCtx) throwIgnorableTestError(FunctionCall) Value {
  270. panic(ignorableTestError)
  271. }
  272. func (ctx *tc39TestCtx) runTC39Test(name, src string, meta *tc39Meta, t testing.TB) {
  273. defer func() {
  274. if x := recover(); x != nil {
  275. panic(fmt.Sprintf("panic while running %s: %v", name, x))
  276. }
  277. }()
  278. vm := New()
  279. _262 := vm.NewObject()
  280. _262.Set("detachArrayBuffer", ctx.detachArrayBuffer)
  281. _262.Set("createRealm", ctx.throwIgnorableTestError)
  282. vm.Set("$262", _262)
  283. vm.Set("IgnorableTestError", ignorableTestError)
  284. vm.Set("print", t.Log)
  285. vm.RunProgram(sabStub)
  286. err, early := ctx.runTC39Script(name, src, meta.Includes, vm)
  287. if err != nil {
  288. if meta.Negative.Type == "" {
  289. if err, ok := err.(*Exception); ok {
  290. if err.Value() == ignorableTestError {
  291. t.Skip("Test threw IgnorableTestError")
  292. }
  293. }
  294. t.Fatalf("%s: %v", name, err)
  295. } else {
  296. if meta.Negative.Phase == "early" && !early || meta.Negative.Phase == "runtime" && early {
  297. t.Fatalf("%s: error %v happened at the wrong phase (expected %s)", name, err, meta.Negative.Phase)
  298. }
  299. var errType string
  300. switch err := err.(type) {
  301. case *Exception:
  302. if o, ok := err.Value().(*Object); ok {
  303. if c := o.Get("constructor"); c != nil {
  304. if c, ok := c.(*Object); ok {
  305. errType = c.Get("name").String()
  306. } else {
  307. t.Fatalf("%s: error constructor is not an object (%v)", name, o)
  308. }
  309. } else {
  310. t.Fatalf("%s: error does not have a constructor (%v)", name, o)
  311. }
  312. } else {
  313. t.Fatalf("%s: error is not an object (%v)", name, err.Value())
  314. }
  315. case *CompilerSyntaxError:
  316. errType = "SyntaxError"
  317. case *CompilerReferenceError:
  318. errType = "ReferenceError"
  319. default:
  320. t.Fatalf("%s: error is not a JS error: %v", name, err)
  321. }
  322. if errType != meta.Negative.Type {
  323. vm.vm.prg.dumpCode(t.Logf)
  324. t.Fatalf("%s: unexpected error type (%s), expected (%s)", name, errType, meta.Negative.Type)
  325. }
  326. }
  327. } else {
  328. if meta.Negative.Type != "" {
  329. vm.vm.prg.dumpCode(t.Logf)
  330. t.Fatalf("%s: Expected error: %v", name, err)
  331. }
  332. }
  333. if vm.vm.sp != 0 {
  334. t.Fatalf("sp: %d", vm.vm.sp)
  335. }
  336. if l := len(vm.vm.iterStack); l > 0 {
  337. t.Fatalf("iter stack is not empty: %d", l)
  338. }
  339. }
  340. func (ctx *tc39TestCtx) runTC39File(name string, t testing.TB) {
  341. if skipList[name] {
  342. t.Skip("Excluded")
  343. }
  344. p := path.Join(ctx.base, name)
  345. meta, src, err := parseTC39File(p)
  346. if err != nil {
  347. //t.Fatalf("Could not parse %s: %v", name, err)
  348. t.Errorf("Could not parse %s: %v", name, err)
  349. return
  350. }
  351. if meta.Es5id == "" {
  352. skip := true
  353. //t.Logf("%s: Not ES5, skipped", name)
  354. if es6WhiteList[name] {
  355. skip = false
  356. } else {
  357. if meta.Es6id != "" {
  358. for _, prefix := range es6IdWhiteList {
  359. if strings.HasPrefix(meta.Es6id, prefix) &&
  360. (len(meta.Es6id) == len(prefix) || meta.Es6id[len(prefix)] == '.') {
  361. skip = false
  362. break
  363. }
  364. }
  365. }
  366. }
  367. if skip {
  368. if meta.Esid != "" {
  369. for _, prefix := range esIdPrefixWhiteList {
  370. if strings.HasPrefix(meta.Esid, prefix) &&
  371. (len(meta.Esid) == len(prefix) || meta.Esid[len(prefix)] == '.') {
  372. skip = false
  373. break
  374. }
  375. }
  376. }
  377. }
  378. if skip {
  379. t.Skip("Not ES5")
  380. }
  381. for _, feature := range meta.Features {
  382. for _, bl := range featuresBlackList {
  383. if feature == bl {
  384. t.Skip("Blacklisted feature")
  385. }
  386. }
  387. }
  388. }
  389. var startTime time.Time
  390. if ctx.enableBench {
  391. startTime = time.Now()
  392. }
  393. hasRaw := meta.hasFlag("raw")
  394. if hasRaw || !meta.hasFlag("onlyStrict") {
  395. //log.Printf("Running normal test: %s", name)
  396. //t.Logf("Running normal test: %s", name)
  397. ctx.runTC39Test(name, src, meta, t)
  398. }
  399. if !hasRaw && !meta.hasFlag("noStrict") {
  400. //log.Printf("Running strict test: %s", name)
  401. //t.Logf("Running strict test: %s", name)
  402. ctx.runTC39Test(name, "'use strict';\n"+src, meta, t)
  403. }
  404. if ctx.enableBench {
  405. ctx.benchLock.Lock()
  406. ctx.benchmark = append(ctx.benchmark, tc39BenchmarkItem{
  407. name: name,
  408. duration: time.Since(startTime),
  409. })
  410. ctx.benchLock.Unlock()
  411. }
  412. }
  413. func (ctx *tc39TestCtx) init() {
  414. ctx.prgCache = make(map[string]*Program)
  415. }
  416. func (ctx *tc39TestCtx) compile(base, name string) (*Program, error) {
  417. ctx.prgCacheLock.Lock()
  418. defer ctx.prgCacheLock.Unlock()
  419. prg := ctx.prgCache[name]
  420. if prg == nil {
  421. fname := path.Join(base, name)
  422. f, err := os.Open(fname)
  423. if err != nil {
  424. return nil, err
  425. }
  426. defer f.Close()
  427. b, err := ioutil.ReadAll(f)
  428. if err != nil {
  429. return nil, err
  430. }
  431. str := string(b)
  432. prg, err = Compile(name, str, false)
  433. if err != nil {
  434. return nil, err
  435. }
  436. ctx.prgCache[name] = prg
  437. }
  438. return prg, nil
  439. }
  440. func (ctx *tc39TestCtx) runFile(base, name string, vm *Runtime) error {
  441. prg, err := ctx.compile(base, name)
  442. if err != nil {
  443. return err
  444. }
  445. _, err = vm.RunProgram(prg)
  446. return err
  447. }
  448. func (ctx *tc39TestCtx) runTC39Script(name, src string, includes []string, vm *Runtime) (err error, early bool) {
  449. early = true
  450. err = ctx.runFile(ctx.base, path.Join("harness", "assert.js"), vm)
  451. if err != nil {
  452. return
  453. }
  454. err = ctx.runFile(ctx.base, path.Join("harness", "sta.js"), vm)
  455. if err != nil {
  456. return
  457. }
  458. for _, include := range includes {
  459. err = ctx.runFile(ctx.base, path.Join("harness", include), vm)
  460. if err != nil {
  461. return
  462. }
  463. }
  464. var p *Program
  465. p, err = Compile(name, src, false)
  466. if err != nil {
  467. return
  468. }
  469. early = false
  470. _, err = vm.RunProgram(p)
  471. return
  472. }
  473. func (ctx *tc39TestCtx) runTC39Tests(name string) {
  474. files, err := ioutil.ReadDir(path.Join(ctx.base, name))
  475. if err != nil {
  476. ctx.t.Fatal(err)
  477. }
  478. for _, file := range files {
  479. if file.Name()[0] == '.' {
  480. continue
  481. }
  482. if file.IsDir() {
  483. ctx.runTC39Tests(path.Join(name, file.Name()))
  484. } else {
  485. if strings.HasSuffix(file.Name(), ".js") {
  486. name := path.Join(name, file.Name())
  487. ctx.runTest(name, func(t *testing.T) {
  488. ctx.runTC39File(name, t)
  489. })
  490. }
  491. }
  492. }
  493. }
  494. func TestTC39(t *testing.T) {
  495. if testing.Short() {
  496. t.Skip()
  497. }
  498. if _, err := os.Stat(tc39BASE); err != nil {
  499. t.Skipf("If you want to run tc39 tests, download them from https://github.com/tc39/test262 and put into %s. The last working commit is 1ba3a7c4a93fc93b3d0d7e4146f59934a896837d. (%v)", tc39BASE, err)
  500. }
  501. ctx := &tc39TestCtx{
  502. base: tc39BASE,
  503. }
  504. ctx.init()
  505. //ctx.enableBench = true
  506. t.Run("tc39", func(t *testing.T) {
  507. ctx.t = t
  508. //ctx.runTC39File("test/language/types/number/8.5.1.js", t)
  509. //ctx.runTC39Tests("test/language")
  510. ctx.runTC39Tests("test/language/expressions")
  511. ctx.runTC39Tests("test/language/arguments-object")
  512. ctx.runTC39Tests("test/language/asi")
  513. ctx.runTC39Tests("test/language/directive-prologue")
  514. ctx.runTC39Tests("test/language/function-code")
  515. ctx.runTC39Tests("test/language/eval-code")
  516. ctx.runTC39Tests("test/language/global-code")
  517. ctx.runTC39Tests("test/language/identifier-resolution")
  518. ctx.runTC39Tests("test/language/identifiers")
  519. //ctx.runTC39Tests("test/language/literals") // octal sequences in strict mode
  520. ctx.runTC39Tests("test/language/punctuators")
  521. ctx.runTC39Tests("test/language/reserved-words")
  522. ctx.runTC39Tests("test/language/source-text")
  523. ctx.runTC39Tests("test/language/statements")
  524. ctx.runTC39Tests("test/language/types")
  525. ctx.runTC39Tests("test/language/white-space")
  526. ctx.runTC39Tests("test/built-ins")
  527. ctx.runTC39Tests("test/annexB/built-ins/String/prototype/substr")
  528. ctx.runTC39Tests("test/annexB/built-ins/escape")
  529. ctx.runTC39Tests("test/annexB/built-ins/unescape")
  530. ctx.runTC39Tests("test/annexB/built-ins/RegExp")
  531. ctx.flush()
  532. })
  533. if ctx.enableBench {
  534. sort.Slice(ctx.benchmark, func(i, j int) bool {
  535. return ctx.benchmark[i].duration > ctx.benchmark[j].duration
  536. })
  537. bench := ctx.benchmark
  538. if len(bench) > 50 {
  539. bench = bench[:50]
  540. }
  541. for _, item := range bench {
  542. fmt.Printf("%s\t%d\n", item.name, item.duration/time.Millisecond)
  543. }
  544. }
  545. }