From d30bb2ef7e3ab35ae772d38d6740377fb6659a0d Mon Sep 17 00:00:00 2001 From: Jamie Wong Date: Mon, 20 Apr 2020 08:26:59 -0700 Subject: [PATCH] Fix the build for node 13.x, make travis test 10, 12, 13, stable (#263) @JustinBeckwith pointed out in #262 that `npm install` was broken in node 13.x, and @DanielRuf pointed in #254 that test fail for node 11+ because of a change to stability of sorting. This PR seeks to address both of those. The installation issue was fixed by just regenerating `package-lock.json` without needing to bump any of the direct dependency versions. The test failure issue requires manual intervention. To fix the sort stability issue, I updated the tests to use the stable sort values (these were all the correct values, though some of the test values were incorrect). To make the suite still pass for node 10, I added a hack where I override `Array.prototype.sort` with a stable implementation that's *only* used in tests (See comments in code for a justification for why) ## Test Plan Before this PR: `npm install` on node 13.x fails & `npm run jest` results in test failures After this PR: `npm install` on node 13.x passes & `npm run jest` passes for node 10, 12, and 13. --- .travis.yml | 5 +- package-lock.json | 658 +----------------- package.json | 7 +- prettier.config.js | 3 +- src/gl/canvas-context.ts | 4 +- src/gl/flamechart-renderer.ts | 8 +- src/gl/overlay-rectangle-renderer.ts | 7 +- src/gl/rectangle-batch-renderer.ts | 9 +- src/import/__snapshots__/chrome.test.ts.snap | 184 ++--- .../__snapshots__/trace-event.test.ts.snap | 34 +- src/jest-setup.js | 51 ++ src/lib/color.ts | 18 +- src/lib/emscripten.test.ts | 17 +- src/lib/file-format.ts | 5 +- src/lib/math.test.ts | 70 +- src/lib/profile.test.ts | 95 +-- src/lib/profile.ts | 13 +- src/lib/stats.ts | 2 +- src/lib/utils.ts | 28 +- src/store/getters.ts | 37 +- src/views/application.tsx | 2 +- src/views/flamechart-detail-view.tsx | 4 +- src/views/flamechart-minimap-view.tsx | 4 +- src/views/flamechart-pan-zoom-view.tsx | 4 +- src/views/flamechart-view.tsx | 2 +- src/views/flamechart-wrapper.tsx | 2 +- src/views/profile-table-view.tsx | 4 +- 27 files changed, 366 insertions(+), 911 deletions(-) create mode 100644 src/jest-setup.js diff --git a/.travis.yml b/.travis.yml index 5e9cd4744..9e8a40c35 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,6 @@ language: node_js node_js: - - '9' + - '10' + - '12' + - '13' + - 'node' diff --git a/package-lock.json b/package-lock.json index 4f2e80eda..ac0fd300a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "speedscope", - "version": "1.5.2", + "version": "1.5.3", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -2458,10 +2458,13 @@ "dev": true }, "bindings": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz", - "integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE=", - "dev": true + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "requires": { + "file-uri-to-path": "1.0.0" + } }, "bluebird": { "version": "3.5.1", @@ -2861,620 +2864,6 @@ "upath": "^1.0.5" }, "dependencies": { - "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.10.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", - "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", - "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true, - "optional": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz", - "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.21", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.21.tgz", - "integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==", - "dev": true, - "optional": true, - "requires": { - "safer-buffer": "^2.1.0" - } - }, - "ignore-walk": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", - "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz", - "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.1", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz", - "integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "optional": true - }, - "needle": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.2.0.tgz", - "integrity": "sha512-eFagy6c+TYayorXw/qtAdSvaUpEbBsDwDyxYFgLZ0lTojfH7K+OdBqAF7TAFwDokJaGpubpSGG0wO3iC0XPi8w==", - "dev": true, - "optional": true, - "requires": { - "debug": "^2.1.2", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.10.0.tgz", - "integrity": "sha512-G7kEonQLRbcA/mOoFoxvlMrw6Q6dPf92+t/l0DFSMuSlDoWaI9JWIyPwK0jyE1bph//CUEL65/Fz1m2vJbmjQQ==", - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.0", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.1.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.3.tgz", - "integrity": "sha512-ByQ3oJ/5ETLyglU2+8dBObvhfWXX8dtPZDMePCahptliFX2iIuhyEszyFk401PZUNQH20vvdW5MLjJxkwU80Ow==", - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.1.10.tgz", - "integrity": "sha512-AQC0Dyhzn4EiYEfIUjCdMl0JJ61I2ER9ukf/sLxJUcZHfo+VyEfz2rMJgLZSS1v30OxPQe1cN0LZA1xbcaVfWA==", - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.7.tgz", - "integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==", - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.5.1", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "optional": true, - "requires": { - "glob": "^7.0.5" - } - }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true, - "optional": true - }, - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.1.tgz", - "integrity": "sha512-O+v1r9yN4tOsvl90p5HAP4AEqbYhx4036AGMm075fH9F8Qwi3oJ+v4u50FkT/KkvywNGtwkk0zRI+8eYm1X/xg==", - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.0.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", - "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", - "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=", - "dev": true, - "optional": true - } - } - }, "glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", @@ -4328,13 +3717,13 @@ "dev": true }, "deasync": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/deasync/-/deasync-0.1.13.tgz", - "integrity": "sha512-/6ngYM7AapueqLtvOzjv9+11N2fHDSrkxeMF1YPE20WIfaaawiBg+HZH1E5lHrcJxlKR42t6XPOEmMmqcAsU1g==", + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/deasync/-/deasync-0.1.19.tgz", + "integrity": "sha512-oh3MRktfnPlLysCPpBpKZZzb4cUC/p0aA3SyRGp15lN30juJBTo/CiD0d4fR+f1kBtUQoJj1NE9RPNWQ7BQ9Mg==", "dev": true, "requires": { - "bindings": "~1.2.1", - "nan": "^2.0.7" + "bindings": "^1.5.0", + "node-addon-api": "^1.7.1" } }, "debug": { @@ -5205,8 +4594,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true + "dev": true }, "filesize": { "version": "3.6.1", @@ -8136,12 +7524,6 @@ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, - "nan": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "dev": true - }, "nanomatch": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", @@ -8194,6 +7576,12 @@ "integrity": "sha512-2NpiFHqC87y/zFke0fC0spBXL3bBsoh/p5H1EFhshxjCR5+0g2d6BiXbUFz9v1sAcxsk2htp2eQnNIci2dIYcA==", "dev": true }, + "node-addon-api": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.1.tgz", + "integrity": "sha512-2+DuKodWvwRTrCfKOeR24KIc5unKjOh8mz17NCzVnHWfjAdDqbfbjqh7gUT+BkXBRQM52+xCHciKWonJ3CbJMQ==", + "dev": true + }, "node-fetch": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", @@ -10955,9 +10343,9 @@ "dev": true }, "prettier": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.12.0.tgz", - "integrity": "sha512-Wz0SMncgaglBzDcohH3ZIAi4nVpzOIEweFzCOmgVEoRSeO72b4dcKGfgxoRGVMaFlh1r7dlVaJ+f3CIHfeH6xg==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.4.tgz", + "integrity": "sha512-SVJIQ51spzFDvh4fIbCLvciiDMCrRhlN3mbZvv/+ycjvmF5E73bKdGfU8QDLNmjYJf+lsGnDBC4UUnvTe5OO0w==", "dev": true }, "pretty-format": { diff --git a/package.json b/package.json index 95de46171..22da71982 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "parcel-bundler": "1.9.2", "preact": "8.2.7", "preact-redux": "jlfwong/preact-redux#a56dcc4", - "prettier": "1.12.0", + "prettier": "2.0.4", "protobufjs": "6.8.8", "quicktype": "15.0.209", "redux": "^4.0.0", @@ -57,6 +57,9 @@ "transform": { "^.+\\.tsx?$": "ts-jest" }, + "setupFilesAfterEnv": [ + "./src/jest-setup.js" + ], "testRegex": "\\.test\\.tsx?$", "collectCoverageFrom": [ "**/*.{ts,tsx}", @@ -73,4 +76,4 @@ "dependencies": { "opn": "5.3.0" } -} +} \ No newline at end of file diff --git a/prettier.config.js b/prettier.config.js index 814bd5246..9b0317bfb 100644 --- a/prettier.config.js +++ b/prettier.config.js @@ -4,4 +4,5 @@ module.exports = { semi: false, singleQuote: true, trailingComma: 'all', -}; + arrowParens: 'avoid' +} diff --git a/src/gl/canvas-context.ts b/src/gl/canvas-context.ts index 98bf8f9de..8af7a946b 100644 --- a/src/gl/canvas-context.ts +++ b/src/gl/canvas-context.ts @@ -24,9 +24,7 @@ export class CanvasContext { const webGLInfo = this.gl.getWebGLInfo() if (webGLInfo) { console.log( - `WebGL initialized. renderer: ${webGLInfo.renderer}, vendor: ${ - webGLInfo.vendor - }, version: ${webGLInfo.version}`, + `WebGL initialized. renderer: ${webGLInfo.renderer}, vendor: ${webGLInfo.vendor}, version: ${webGLInfo.version}`, ) } ;(window as any)['testContextLoss'] = () => { diff --git a/src/gl/flamechart-renderer.ts b/src/gl/flamechart-renderer.ts index 4bce19d86..b10d8b4e9 100644 --- a/src/gl/flamechart-renderer.ts +++ b/src/gl/flamechart-renderer.ts @@ -175,8 +175,8 @@ export class FlamechartRenderer { // and the blue channel to indicate the color bucket to render. // We add one to each so we have zero reserved for the background color. const color = new Color( - (1 + i % 255) / 256, - (1 + stackDepth % 255) / 256, + (1 + (i % 255)) / 256, + (1 + (stackDepth % 255)) / 256, (1 + this.flamechart.getColorBucketForFrame(frame.node.frame)) / 256, ) batch.addRect(configSpaceBounds, color) @@ -288,10 +288,10 @@ export class FlamechartRenderer { const configSpaceContentWidth = this.flamechart.getTotalWeight() const numAtlasEntriesPerLayer = Math.pow(2, zoomLevel) const left = Math.floor( - numAtlasEntriesPerLayer * configSpaceSrcRect.left() / configSpaceContentWidth, + (numAtlasEntriesPerLayer * configSpaceSrcRect.left()) / configSpaceContentWidth, ) const right = Math.ceil( - numAtlasEntriesPerLayer * configSpaceSrcRect.right() / configSpaceContentWidth, + (numAtlasEntriesPerLayer * configSpaceSrcRect.right()) / configSpaceContentWidth, ) const nLayers = this.flamechart.getLayers().length diff --git a/src/gl/overlay-rectangle-renderer.ts b/src/gl/overlay-rectangle-renderer.ts index 6634355c0..9050deee5 100644 --- a/src/gl/overlay-rectangle-renderer.ts +++ b/src/gl/overlay-rectangle-renderer.ts @@ -65,7 +65,12 @@ export class ViewportRectangleRenderer { private buffer: Graphics.VertexBuffer constructor(private gl: Graphics.Context) { - const vertices = [[-1, 1], [1, 1], [-1, -1], [1, -1]] + const vertices = [ + [-1, 1], + [1, 1], + [-1, -1], + [1, -1], + ] const floats: number[] = [] for (let v of vertices) { floats.push(v[0]) diff --git a/src/gl/rectangle-batch-renderer.ts b/src/gl/rectangle-batch-renderer.ts index 58489358a..ce4a61f03 100644 --- a/src/gl/rectangle-batch-renderer.ts +++ b/src/gl/rectangle-batch-renderer.ts @@ -45,7 +45,14 @@ export class RectangleBatch { return this.buffer } - const corners = [[0, 0], [1, 0], [0, 1], [1, 0], [0, 1], [1, 1]] + const corners = [ + [0, 0], + [1, 0], + [0, 1], + [1, 0], + [0, 1], + [1, 1], + ] const bytes = new Uint8Array(vertexFormat.stride * corners.length * this.rects.length) const floats = new Float32Array(bytes.buffer) diff --git a/src/import/__snapshots__/chrome.test.ts.snap b/src/import/__snapshots__/chrome.test.ts.snap index 77c4b7a7f..c9601dbc1 100644 --- a/src/import/__snapshots__/chrome.test.ts.snap +++ b/src/import/__snapshots__/chrome.test.ts.snap @@ -516,97 +516,6 @@ exports[`importFromChromeTimeline Chrome 69: indexToView 1`] = `0`; exports[`importFromChromeTimeline Chrome 69: profileGroup.name 1`] = `"simple.json"`; exports[`importFromChromeTimeline Workers Chrome 66 1`] = ` -Object { - "frames": Array [ - Frame { - "col": -1, - "file": "", - "key": "(program)::-1:-1", - "line": -1, - "name": "(program)", - "selfWeight": 819120, - "totalWeight": 819120, - }, - Frame { - "col": 20, - "file": "http://172.30.3.176:7777/worker.js", - "key": "onmessage:http://172.30.3.176:7777/worker.js:14:20", - "line": 14, - "name": "onmessage", - "selfWeight": 639, - "totalWeight": 857719, - }, - Frame { - "col": 14, - "file": "http://172.30.3.176:7777/worker.js", - "key": "alpha:http://172.30.3.176:7777/worker.js:8:14", - "line": 8, - "name": "alpha", - "selfWeight": 19976, - "totalWeight": 835149, - }, - Frame { - "col": 14, - "file": "http://172.30.3.176:7777/worker.js", - "key": "gamma:http://172.30.3.176:7777/worker.js:0:14", - "line": 0, - "name": "gamma", - "selfWeight": 22197, - "totalWeight": 30000, - }, - Frame { - "col": -1, - "file": "", - "key": "postMessage::-1:-1", - "line": -1, - "name": "postMessage", - "selfWeight": 1278, - "totalWeight": 21931, - }, - ], - "name": "worker.json - DedicatedWorker thread", - "stacks": Array [ - " 9.07ms", - "(program) 5.49ms", - "onmessage;alpha;gamma 3.69ms", - "onmessage;postMessage 212.00µs", - "onmessage;postMessage;(program) 3.97ms", - "onmessage;alpha;gamma 3.82ms", - "onmessage;postMessage 414.00µs", - "onmessage;postMessage;(program) 3.71ms", - "onmessage;alpha;gamma 1.13ms", - "onmessage 188.00µs", - "onmessage;alpha;gamma 2.48ms", - "onmessage;alpha;gamma;(program) 3.89ms", - "onmessage;alpha;gamma 373.00µs", - "onmessage;alpha 184.00µs", - "onmessage;alpha;gamma 3.36ms", - "onmessage;alpha;gamma;(program) 3.91ms", - "onmessage;alpha;gamma 3.94ms", - "onmessage;postMessage 205.00µs", - "onmessage;postMessage;(program) 3.91ms", - "onmessage 451.00µs", - "onmessage;alpha;gamma 566.00µs", - "onmessage;alpha 194.00µs", - "onmessage;alpha;gamma 2.09ms", - "onmessage;alpha 189.00µs", - "onmessage;alpha;gamma 746.00µs", - "onmessage;postMessage 211.00µs", - "onmessage;postMessage;(program) 4.00ms", - "onmessage;alpha 4.80ms", - "onmessage;alpha;(program) 5.28ms", - "onmessage;alpha 4.70ms", - "onmessage;postMessage 236.00µs", - "onmessage;postMessage;(program) 5.06ms", - "onmessage;alpha 5.07ms", - "onmessage;alpha;(program) 4.81ms", - "onmessage;alpha 4.84ms", - "onmessage;alpha;(program) 775.08ms", - ], -} -`; - -exports[`importFromChromeTimeline Workers Chrome 66 2`] = ` Object { "frames": Array [ Frame { @@ -913,7 +822,98 @@ Object { } `; -exports[`importFromChromeTimeline Workers Chrome 66: indexToView 1`] = `1`; +exports[`importFromChromeTimeline Workers Chrome 66 2`] = ` +Object { + "frames": Array [ + Frame { + "col": -1, + "file": "", + "key": "(program)::-1:-1", + "line": -1, + "name": "(program)", + "selfWeight": 819120, + "totalWeight": 819120, + }, + Frame { + "col": 20, + "file": "http://172.30.3.176:7777/worker.js", + "key": "onmessage:http://172.30.3.176:7777/worker.js:14:20", + "line": 14, + "name": "onmessage", + "selfWeight": 639, + "totalWeight": 857719, + }, + Frame { + "col": 14, + "file": "http://172.30.3.176:7777/worker.js", + "key": "alpha:http://172.30.3.176:7777/worker.js:8:14", + "line": 8, + "name": "alpha", + "selfWeight": 19976, + "totalWeight": 835149, + }, + Frame { + "col": 14, + "file": "http://172.30.3.176:7777/worker.js", + "key": "gamma:http://172.30.3.176:7777/worker.js:0:14", + "line": 0, + "name": "gamma", + "selfWeight": 22197, + "totalWeight": 30000, + }, + Frame { + "col": -1, + "file": "", + "key": "postMessage::-1:-1", + "line": -1, + "name": "postMessage", + "selfWeight": 1278, + "totalWeight": 21931, + }, + ], + "name": "worker.json - DedicatedWorker thread", + "stacks": Array [ + " 9.07ms", + "(program) 5.49ms", + "onmessage;alpha;gamma 3.69ms", + "onmessage;postMessage 212.00µs", + "onmessage;postMessage;(program) 3.97ms", + "onmessage;alpha;gamma 3.82ms", + "onmessage;postMessage 414.00µs", + "onmessage;postMessage;(program) 3.71ms", + "onmessage;alpha;gamma 1.13ms", + "onmessage 188.00µs", + "onmessage;alpha;gamma 2.48ms", + "onmessage;alpha;gamma;(program) 3.89ms", + "onmessage;alpha;gamma 373.00µs", + "onmessage;alpha 184.00µs", + "onmessage;alpha;gamma 3.36ms", + "onmessage;alpha;gamma;(program) 3.91ms", + "onmessage;alpha;gamma 3.94ms", + "onmessage;postMessage 205.00µs", + "onmessage;postMessage;(program) 3.91ms", + "onmessage 451.00µs", + "onmessage;alpha;gamma 566.00µs", + "onmessage;alpha 194.00µs", + "onmessage;alpha;gamma 2.09ms", + "onmessage;alpha 189.00µs", + "onmessage;alpha;gamma 746.00µs", + "onmessage;postMessage 211.00µs", + "onmessage;postMessage;(program) 4.00ms", + "onmessage;alpha 4.80ms", + "onmessage;alpha;(program) 5.28ms", + "onmessage;alpha 4.70ms", + "onmessage;postMessage 236.00µs", + "onmessage;postMessage;(program) 5.06ms", + "onmessage;alpha 5.07ms", + "onmessage;alpha;(program) 4.81ms", + "onmessage;alpha 4.84ms", + "onmessage;alpha;(program) 775.08ms", + ], +} +`; + +exports[`importFromChromeTimeline Workers Chrome 66: indexToView 1`] = `0`; exports[`importFromChromeTimeline Workers Chrome 66: profileGroup.name 1`] = `"worker.json"`; diff --git a/src/import/__snapshots__/trace-event.test.ts.snap b/src/import/__snapshots__/trace-event.test.ts.snap index 9fde686f6..0d31032b2 100644 --- a/src/import/__snapshots__/trace-event.test.ts.snap +++ b/src/import/__snapshots__/trace-event.test.ts.snap @@ -44,26 +44,26 @@ Object { "key": "A", "line": undefined, "name": "A", - "selfWeight": 1, - "totalWeight": 10, + "selfWeight": 2, + "totalWeight": 6, }, Frame { "col": undefined, "file": undefined, - "key": "C", + "key": "B", "line": undefined, - "name": "C", - "selfWeight": 3, - "totalWeight": 10, + "name": "B", + "selfWeight": 2, + "totalWeight": 4, }, Frame { "col": undefined, "file": undefined, - "key": "B", + "key": "C", "line": undefined, - "name": "B", - "selfWeight": 3, - "totalWeight": 4, + "name": "C", + "selfWeight": 2, + "totalWeight": 2, }, Frame { "col": undefined, @@ -77,12 +77,14 @@ Object { ], "name": "pid 0, tid 1", "stacks": Array [ - "A;C;B 2.00µs", - "A;C 2.00µs", - "A;C;A 1.00µs", - "A;C;A;B 1.00µs", - "A;C;A;B;C 1.00µs", - "A;C;X 3.00µs", + "A;B;C 1.00µs", + "A;B 1.00µs", + "A 1.00µs", + " 1.00µs", + "A 1.00µs", + "A;B 1.00µs", + "A;B;C 1.00µs", + "X 3.00µs", ], } `; diff --git a/src/jest-setup.js b/src/jest-setup.js new file mode 100644 index 000000000..4bb67f391 --- /dev/null +++ b/src/jest-setup.js @@ -0,0 +1,51 @@ +// Versions of node before 10 had an unstable sort. This isn't really an issue in browsers +// that speedscope supports, but for the purposes of supporting node 10, we'll polyfill +// a stable sort to make the tests pass. +// +// See: +// - https://v8.dev/features/stable-sort +// - https://v8.dev/blog/array-sort +// - https://github.com/jlfwong/speedscope/pull/254#issuecomment-575116995 +// +// Once we stop supporting node 10, this can be removed. +// +// An alternative would be to change our sort implementation to be stable by definition +// rather than relying upon native sort being stable. I don't want to do that because +// we'd take a perf hit. +// +// Because we're not going to use this in our actual build, it's okay for this +// to be inefficient. + +(function () { + const nodeVersion = process.versions.node + const versionParts = nodeVersion.split('.') + const majorVersion = parseInt(versionParts[0], 10) + + if (majorVersion > 10) { + // Don't need to do the patch for newer node versions + return + } + + const defaultCompareFunction = (a, b) => { + const sa = '' + a + const sb = '' + b + if (sa < sb) return -1 + if (sa > sb) return 1 + return 0 + } + + const originalSort = Array.prototype.sort + Array.prototype.sort = function (compareFunction) { + const arrayWithIndices = this.map((x, i) => [x, i]) + originalSort.call(arrayWithIndices, (a, b) => { + if (!compareFunction) { + compareFunction = defaultCompareFunction + } + const res = compareFunction(a[0], b[0]) + if (res !== 0) return res + return a[1] < b[1] ? -1 : 1 + }) + this.splice(0, this.length, ...arrayWithIndices.map(x => x[0])) + return this + } +})() \ No newline at end of file diff --git a/src/lib/color.ts b/src/lib/color.ts index 92dcce1b9..8649a8bb0 100644 --- a/src/lib/color.ts +++ b/src/lib/color.ts @@ -15,19 +15,19 @@ export class Color { // https://en.wikipedia.org/wiki/HSL_and_HSV#From_luma/chroma/hue const hPrime = H / 60 - const X = C * (1 - Math.abs(hPrime % 2 - 1)) + const X = C * (1 - Math.abs((hPrime % 2) - 1)) const [R1, G1, B1] = hPrime < 1 ? [C, X, 0] : hPrime < 2 - ? [X, C, 0] - : hPrime < 3 - ? [0, C, X] - : hPrime < 4 - ? [0, X, C] - : hPrime < 5 - ? [X, 0, C] - : [C, 0, X] + ? [X, C, 0] + : hPrime < 3 + ? [0, C, X] + : hPrime < 4 + ? [0, X, C] + : hPrime < 5 + ? [X, 0, C] + : [C, 0, X] const m = L - (0.3 * R1 + 0.59 * G1 + 0.11 * B1) diff --git a/src/lib/emscripten.test.ts b/src/lib/emscripten.test.ts index cd2ab94a6..79f434cc7 100644 --- a/src/lib/emscripten.test.ts +++ b/src/lib/emscripten.test.ts @@ -11,7 +11,13 @@ test('importEmscriptenSymbolMap', () => { 'c:C', ].join('\n'), ), - ).toEqual(new Map([['a', 'A'], ['b', 'B'], ['c', 'C']])) + ).toEqual( + new Map([ + ['a', 'A'], + ['b', 'B'], + ['c', 'C'], + ]), + ) // Valid symbol map with trailing newline expect( @@ -25,7 +31,14 @@ test('importEmscriptenSymbolMap', () => { '', ].join('\n'), ), - ).toEqual(new Map([['a', 'A'], ['b', 'B'], ['c', 'C'], ['d', 'D-D']])) + ).toEqual( + new Map([ + ['a', 'A'], + ['b', 'B'], + ['c', 'C'], + ['d', 'D-D'], + ]), + ) // Valid symbol map with non-alpha characters expect(importEmscriptenSymbolMap('u6:__ZN8tinyxml210XMLCommentD0Ev\n')).toEqual( diff --git a/src/lib/file-format.ts b/src/lib/file-format.ts index 237ba67e6..2ec5eee96 100644 --- a/src/lib/file-format.ts +++ b/src/lib/file-format.ts @@ -138,7 +138,10 @@ function importSpeedscopeProfile( for (let i = 0; i < samples.length; i++) { const stack = samples[i] const weight = weights[i] - profile.appendSampleWithWeight(stack.map(n => frameInfos[n]), weight) + profile.appendSampleWithWeight( + stack.map(n => frameInfos[n]), + weight, + ) } return profile.build() diff --git a/src/lib/math.test.ts b/src/lib/math.test.ts index 3f4ec3273..eca343c40 100644 --- a/src/lib/math.test.ts +++ b/src/lib/math.test.ts @@ -13,9 +13,10 @@ test('clamp', () => { // Change this to jsc.integer to debug failures more easily let numericType = jsc.number -const arbitraryVec2 = jsc - .record({x: jsc.integer, y: numericType}) - .smap(v => new Vec2(v.x, v.y), v => v) +const arbitraryVec2 = jsc.record({x: jsc.integer, y: numericType}).smap( + v => new Vec2(v.x, v.y), + v => v, +) const positiveVec2 = jsc.suchthat(arbitraryVec2, v => v.x > 0 && v.y > 0) @@ -28,23 +29,25 @@ const arbitraryTransform = jsc m11: numericType, m12: numericType, }) - .smap(t => new AffineTransform(t.m00, t.m01, t.m02, t.m10, t.m11, t.m12), t => t) + .smap( + t => new AffineTransform(t.m00, t.m01, t.m02, t.m10, t.m11, t.m12), + t => t, + ) const invertibleTransform = jsc.suchthat(arbitraryTransform, t => t.det() != 0) const simpleTransform = jsc.suchthat( - jsc - .record({scale: arbitraryVec2, translation: arbitraryVec2}) - .smap( - t => AffineTransform.withScale(t.scale).withTranslation(t.translation), - t => ({scale: t.getScale(), translation: t.getTranslation()}), - ), + jsc.record({scale: arbitraryVec2, translation: arbitraryVec2}).smap( + t => AffineTransform.withScale(t.scale).withTranslation(t.translation), + t => ({scale: t.getScale(), translation: t.getTranslation()}), + ), t => t.det() != 0, ) -const arbitraryRect = jsc - .record({origin: arbitraryVec2, size: positiveVec2}) - .smap(r => new Rect(r.origin, r.size), r => r) +const arbitraryRect = jsc.record({origin: arbitraryVec2, size: positiveVec2}).smap( + r => new Rect(r.origin, r.size), + r => r, +) describe('Vec2', () => { test('constructor', () => { @@ -263,51 +266,35 @@ describe('AffineTransform', () => { expect(new AffineTransform(0, 0, 0, 0, 0, 0).inverted()).toBe(null) jsc.assertForall(invertibleTransform, t => { - return t - .inverted()! - .inverted()! - .approxEquals(t) + return t.inverted()!.inverted()!.approxEquals(t) }) }) test('translation', () => { jsc.assertForall(arbitraryTransform, arbitraryVec2, (t, v1) => { - return t - .withTranslation(v1) - .getTranslation() - .equals(v1) + return t.withTranslation(v1).getTranslation().equals(v1) }) jsc.assertForall(arbitraryTransform, arbitraryVec2, (t, v1) => { const initialTranslation = t.getTranslation() - return t - .translatedBy(v1) - .getTranslation() - .approxEquals(initialTranslation.plus(v1)) + return t.translatedBy(v1).getTranslation().approxEquals(initialTranslation.plus(v1)) }) }) test('scale', () => { jsc.assertForall(arbitraryTransform, arbitraryVec2, (t, v1) => { - return t - .withScale(v1) - .getScale() - .equals(v1) + return t.withScale(v1).getScale().equals(v1) }) }) test('transformVector', () => { // Vector transformation are translation-invariant jsc.assertForall(arbitraryVec2, arbitraryVec2, (v1, v2) => { - return AffineTransform.withTranslation(v1) - .transformVector(v2) - .approxEquals(v2) + return AffineTransform.withTranslation(v1).transformVector(v2).approxEquals(v2) }) jsc.assertForall(arbitraryVec2, arbitraryVec2, (v1, v2) => { - return AffineTransform.withScale(v1) - .transformVector(v2) - .approxEquals(v2.timesPointwise(v1)) + return AffineTransform.withScale(v1).transformVector(v2).approxEquals(v2.timesPointwise(v1)) }) }) @@ -319,15 +306,11 @@ describe('AffineTransform', () => { test('transformPosition', () => { jsc.assertForall(arbitraryVec2, arbitraryVec2, (v1, v2) => { - return AffineTransform.withTranslation(v1) - .transformPosition(v2) - .approxEquals(v2.plus(v1)) + return AffineTransform.withTranslation(v1).transformPosition(v2).approxEquals(v2.plus(v1)) }) jsc.assertForall(arbitraryVec2, arbitraryVec2, (v1, v2) => { - return AffineTransform.withScale(v1) - .transformPosition(v2) - .approxEquals(v2.timesPointwise(v1)) + return AffineTransform.withScale(v1).transformPosition(v2).approxEquals(v2.timesPointwise(v1)) }) }) @@ -359,10 +342,7 @@ describe('AffineTransform', () => { test('times', () => { jsc.assertForall(invertibleTransform, invertibleTransform, (t1, t2) => { - return t1 - .times(t2) - .times(t2.inverted()!) - .approxEquals(t1) + return t1.times(t2).times(t2.inverted()!).approxEquals(t1) }) }) }) diff --git a/src/lib/profile.test.ts b/src/lib/profile.test.ts index 8496ceed2..0920d1161 100644 --- a/src/lib/profile.test.ts +++ b/src/lib/profile.test.ts @@ -26,19 +26,22 @@ function toStackList(profile: Profile, grouped: boolean): string[] { const curStack: (number | string)[] = [] let lastValue = 0 - function openFrame(node: CallTreeNode, value: number) { + function maybeEmit(value: number) { if (lastValue != value) { - stackList.push(curStack.map(k => `${k}`).join(';')) + stackList.push( + curStack.map(k => `${k}`).join(';') + ` ${profile.formatValue(value - lastValue)}`, + ) lastValue = value } - curStack.push(node.frame.key) + } + + function openFrame(node: CallTreeNode, value: number) { + maybeEmit(value) + curStack.push(node.frame.name) } function closeFrame(node: CallTreeNode, value: number) { - if (lastValue != value) { - stackList.push(curStack.map(k => `${k}`).join(';')) - lastValue = value - } + maybeEmit(value) curStack.pop() } @@ -82,49 +85,49 @@ function verifyProfile(profile: Profile) { expect(toStackList(profile, false)).toEqual([ // prettier-ignore - 'a', - 'a;b', - 'a;b;d', - 'a;b;c', - '', - 'a', - 'a;b', - 'a;b;b', - 'a;b;e', - 'a', + 'a 1', + 'a;b 2', + 'a;b;d 1', + 'a;b;c 1', + ' 1', + 'a 1', + 'a;b 1', + 'a;b;b 1', + 'a;b;e 1', + 'a 1', ]) expect(toStackList(profile, true)).toEqual([ // prettier-ignore - 'a;b;e', - 'a;b;b', - 'a;b;c', - 'a;b;d', - 'a;b', - 'a', + 'a;b;d 1', + 'a;b;c 1', + 'a;b;b 1', + 'a;b;e 1', + 'a;b 3', + 'a 3', ]) const flattened = profile.getProfileWithRecursionFlattened() expect(toStackList(flattened, false)).toEqual([ // prettier-ignore - 'a', - 'a;b', - 'a;b;d', - 'a;b;c', - '', - 'a', - 'a;b', - 'a;b;e', - 'a', + 'a 1', + 'a;b 2', + 'a;b;d 1', + 'a;b;c 1', + ' 1', + 'a 1', + 'a;b 2', + 'a;b;e 1', + 'a 1', ]) expect(toStackList(flattened, true)).toEqual([ // prettier-ignore - 'a;b;e', - 'a;b;c', - 'a;b;d', - 'a;b', - 'a', + 'a;b;d 1', + 'a;b;c 1', + 'a;b;e 1', + 'a;b 4', + 'a 3', ]) } @@ -259,9 +262,9 @@ test('getInvertedProfileForCallersOf', () => { expect(toStackList(inverted, false)).toEqual([ // prettier-ignore - 'b', - 'b;a', - 'b;d', + 'b 1', + 'b;a 3', + 'b;d 1', ]) }) @@ -287,10 +290,10 @@ test('getProfileForCalleesOf', () => { expect(toStackList(inverted, false)).toEqual([ // prettier-ignore - 'b', - 'b;c', - 'b;d', - 'b', + 'b 2', + 'b;c 1', + 'b;d 1', + 'b 1', ]) }) @@ -313,8 +316,8 @@ test('getProfileWithRecursionFlattened', () => { expect(toStackList(inverted, false)).toEqual([ // prettier-ignore - 'a', - 'a;b', + 'a 1', + 'a;b 3', ]) const framesInProfile = new Set() diff --git a/src/lib/profile.ts b/src/lib/profile.ts index f1db730ab..58529372e 100644 --- a/src/lib/profile.ts +++ b/src/lib/profile.ts @@ -181,9 +181,9 @@ export class Profile { let childTime = 0 const children = [...node.children] - children.sort((a, b) => (a.getTotalWeight() > b.getTotalWeight() ? -1 : 1)) + children.sort((a, b) => -(a.getTotalWeight() - b.getTotalWeight())) - children.forEach(function(child) { + children.forEach(function (child) { visit(child, start + childTime) childTime += child.getTotalWeight() }) @@ -507,7 +507,10 @@ export class StackListProfileBuilder extends Profile { this.setValueFormatter(new RawValueFormatter()) } } - this.totalWeight = Math.max(this.totalWeight, this.weights.reduce((a, b) => a + b, 0)) + this.totalWeight = Math.max( + this.totalWeight, + this.weights.reduce((a, b) => a + b, 0), + ) return this } } @@ -557,9 +560,7 @@ export class CallTreeProfileBuilder extends Profile { this.weights.push(value - this.lastValue) } else if (delta < 0) { throw new Error( - `Samples must be provided in increasing order of cumulative value. Last sample was ${ - this.lastValue - }, this sample was ${value}`, + `Samples must be provided in increasing order of cumulative value. Last sample was ${this.lastValue}, this sample was ${value}`, ) } } diff --git a/src/lib/stats.ts b/src/lib/stats.ts index 284b5ea7a..a1a2dbd59 100644 --- a/src/lib/stats.ts +++ b/src/lib/stats.ts @@ -53,7 +53,7 @@ export class StatsPanel { this.msPanel.update(time - this.beginTime, 200) if (time >= this.prevTime + 1000) { - this.fpsPanel.update(this.frames * 1000 / (time - this.prevTime), 100) + this.fpsPanel.update((this.frames * 1000) / (time - this.prevTime), 100) this.prevTime = time this.frames = 0 } diff --git a/src/lib/utils.ts b/src/lib/utils.ts index b1dec3059..46fc98ac4 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -4,7 +4,9 @@ export function lastOf(ts: T[]): T | null { export function sortBy(ts: T[], key: (t: T) => number | string): void { function comparator(a: T, b: T) { - return key(a) < key(b) ? -1 : 1 + const keyA = key(a) + const keyB = key(b) + return keyA < keyB ? -1 : keyA > keyB ? 1 : 0 } ts.sort(comparator) } @@ -178,15 +180,17 @@ export function lazyStatic(cb: () => T): () => T { } } -const base64lookupTable = lazyStatic((): Map => { - const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' - const ret = new Map() - for (let i = 0; i < alphabet.length; i++) { - ret.set(alphabet.charAt(i), i) - } - ret.set('=', -1) - return ret -}) +const base64lookupTable = lazyStatic( + (): Map => { + const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' + const ret = new Map() + for (let i = 0; i < alphabet.length; i++) { + ret.set(alphabet.charAt(i), i) + } + ret.set('=', -1) + return ret + }, +) // NOTE: There are probably simpler solutions to this problem, but I have this written already, so // until we run into problems with this, let's just use this. @@ -210,9 +214,7 @@ export function decodeBase64(encoded: string): Uint8Array { if (encoded.length % 4 !== 0) { throw new Error( - `Invalid length for base64 encoded string. Expected length % 4 = 0, got length = ${ - encoded.length - }`, + `Invalid length for base64 encoded string. Expected length % 4 = 0, got length = ${encoded.length}`, ) } diff --git a/src/store/getters.ts b/src/store/getters.ts index c80e908db..752abee2a 100644 --- a/src/store/getters.ts +++ b/src/store/getters.ts @@ -49,23 +49,22 @@ export const getProfileToView = memoizeByShallowEquality( return flattenRecursion ? profile.getProfileWithRecursionFlattened() : profile }, ) -export const getFrameToColorBucket = memoizeByReference((profile: Profile): Map< - string | number, - number -> => { - const frames: Frame[] = [] - profile.forEachFrame(f => frames.push(f)) - function key(f: Frame) { - return (f.file || '') + f.name - } - function compare(a: Frame, b: Frame) { - return key(a) > key(b) ? 1 : -1 - } - frames.sort(compare) - const frameToColorBucket = new Map() - for (let i = 0; i < frames.length; i++) { - frameToColorBucket.set(frames[i].key, Math.floor(255 * i / frames.length)) - } +export const getFrameToColorBucket = memoizeByReference( + (profile: Profile): Map => { + const frames: Frame[] = [] + profile.forEachFrame(f => frames.push(f)) + function key(f: Frame) { + return (f.file || '') + f.name + } + function compare(a: Frame, b: Frame) { + return key(a) > key(b) ? 1 : -1 + } + frames.sort(compare) + const frameToColorBucket = new Map() + for (let i = 0; i < frames.length; i++) { + frameToColorBucket.set(frames[i].key, Math.floor((255 * i) / frames.length)) + } - return frameToColorBucket -}) + return frameToColorBucket + }, +) diff --git a/src/views/application.tsx b/src/views/application.tsx index ce26a316a..c7b9de2a0 100644 --- a/src/views/application.tsx +++ b/src/views/application.tsx @@ -678,7 +678,7 @@ export class Application extends StatelessComponent {
{this.renderContent()}
{this.props.dragActive &&
} diff --git a/src/views/flamechart-detail-view.tsx b/src/views/flamechart-detail-view.tsx index 26a7ab56f..30d78971d 100644 --- a/src/views/flamechart-detail-view.tsx +++ b/src/views/flamechart-detail-view.tsx @@ -19,8 +19,8 @@ class StatisticsTable extends Component { render() { const total = this.props.formatter(this.props.selectedTotal) const self = this.props.formatter(this.props.selectedSelf) - const totalPerc = 100.0 * this.props.selectedTotal / this.props.grandTotal - const selfPerc = 100.0 * this.props.selectedSelf / this.props.grandTotal + const totalPerc = (100.0 * this.props.selectedTotal) / this.props.grandTotal + const selfPerc = (100.0 * this.props.selectedSelf) / this.props.grandTotal return (
diff --git a/src/views/flamechart-minimap-view.tsx b/src/views/flamechart-minimap-view.tsx index 04d3d3377..acaeb039f 100644 --- a/src/views/flamechart-minimap-view.tsx +++ b/src/views/flamechart-minimap-view.tsx @@ -120,9 +120,7 @@ export class FlamechartMinimapView extends Component { formatValue(weight: number) { const totalWeight = this.props.flamechart.getTotalWeight() - const percent = 100 * weight / totalWeight + const percent = (100 * weight) / totalWeight const formattedPercent = formatPercent(percent) return `${this.props.flamechart.formatValue(weight)} (${formattedPercent})` } diff --git a/src/views/flamechart-wrapper.tsx b/src/views/flamechart-wrapper.tsx index 9e27aa493..62a6642dd 100644 --- a/src/views/flamechart-wrapper.tsx +++ b/src/views/flamechart-wrapper.tsx @@ -34,7 +34,7 @@ export class FlamechartWrapper extends StatelessComponent { } private formatValue(weight: number) { const totalWeight = this.props.flamechart.getTotalWeight() - const percent = 100 * weight / totalWeight + const percent = (100 * weight) / totalWeight const formattedPercent = formatPercent(percent) return `${this.props.flamechart.formatValue(weight)} (${formattedPercent})` } diff --git a/src/views/profile-table-view.tsx b/src/views/profile-table-view.tsx index e292f9190..1a7af8c40 100644 --- a/src/views/profile-table-view.tsx +++ b/src/views/profile-table-view.tsx @@ -83,8 +83,8 @@ export class ProfileTableView extends Component { const totalWeight = frame.getTotalWeight() const selfWeight = frame.getSelfWeight() - const totalPerc = 100.0 * totalWeight / profile.getTotalNonIdleWeight() - const selfPerc = 100.0 * selfWeight / profile.getTotalNonIdleWeight() + const totalPerc = (100.0 * totalWeight) / profile.getTotalNonIdleWeight() + const selfPerc = (100.0 * selfWeight) / profile.getTotalNonIdleWeight() const selected = frame === selectedFrame