From 07429172a54b1a893cb325480896e4f8410ab25f Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Fri, 26 Jan 2024 19:12:42 -0300 Subject: [PATCH 01/15] Add logger for test runner --- package-lock.json | 602 +++++++++++++++++++++++++++++++++++++++++-- package.json | 1 + src/commands/test.ts | 14 +- src/logger.ts | 15 ++ src/time-measurer.ts | 15 ++ src/utils.ts | 7 +- 6 files changed, 627 insertions(+), 27 deletions(-) create mode 100644 src/logger.ts create mode 100644 src/time-measurer.ts diff --git a/package-lock.json b/package-lock.json index 2dba483..47957cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "wollok-ts-cli", - "version": "0.1.2", + "version": "0.2.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "wollok-ts-cli", - "version": "0.1.2", + "version": "0.2.0", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -20,6 +20,7 @@ "p5": "^1.8.0", "pkg": "^5.8.1", "socket.io": "^4.5.1", + "winston": "^3.11.0", "wollok-ts": "4.0.6" }, "bin": { @@ -734,6 +735,14 @@ "node": ">=6.9.0" } }, + "node_modules/@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -756,6 +765,16 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@dabh/diagnostics": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "dependencies": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -1282,6 +1301,11 @@ "@types/node": "*" } }, + "node_modules/@types/triple-beam": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", + "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.9.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.1.tgz", @@ -1564,13 +1588,6 @@ "node": ">=6" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/ansi-styles": { "version": "4.3.0", "license": "MIT", @@ -1650,6 +1667,11 @@ "node": "*" } }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -2071,6 +2093,34 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "license": "MIT", @@ -2085,6 +2135,37 @@ "version": "1.1.4", "license": "MIT" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/colorspace": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "dependencies": { + "color": "^3.1.3", + "text-hex": "1.0.x" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -2406,6 +2487,11 @@ "version": "8.0.0", "license": "MIT" }, + "node_modules/enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, "node_modules/encodeurl": { "version": "1.0.2", "license": "MIT", @@ -2590,6 +2676,27 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", @@ -2804,6 +2911,11 @@ "reusify": "^1.0.4" } }, + "node_modules/fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -2913,6 +3025,11 @@ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, + "node_modules/fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, "node_modules/foreground-child": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", @@ -3427,6 +3544,11 @@ "node": ">= 0.10" } }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/is-binary-path": { "version": "2.1.0", "dev": true, @@ -3513,7 +3635,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, "engines": { "node": ">=8" }, @@ -3767,6 +3888,11 @@ "json-buffer": "3.0.1" } }, + "node_modules/kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -3831,6 +3957,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/logform": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz", + "integrity": "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==", + "dependencies": { + "@colors/colors": "1.6.0", + "@types/triple-beam": "^1.3.2", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/loglevel": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.1.tgz", @@ -4293,6 +4435,15 @@ "node": ">=8.9" } }, + "node_modules/nyc/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/nyc/node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -4383,6 +4534,18 @@ "node": ">=8" } }, + "node_modules/nyc/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/nyc/node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -4470,6 +4633,14 @@ "wrappy": "1" } }, + "node_modules/one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "dependencies": { + "fn.name": "1.x.x" + } + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -5133,6 +5304,14 @@ "version": "5.1.2", "license": "MIT" }, + "node_modules/safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "engines": { + "node": ">=10" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "license": "MIT" @@ -5349,6 +5528,14 @@ "simple-concat": "^1.0.0" } }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, "node_modules/sinon": { "version": "17.0.1", "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", @@ -5452,6 +5639,14 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "engines": { + "node": "*" + } + }, "node_modules/statuses": { "version": "2.0.1", "license": "MIT", @@ -5486,9 +5681,18 @@ "node": ">=8" } }, - "node_modules/strip-ansi": { + "node_modules/string-width/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { "version": "6.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -5629,6 +5833,11 @@ "node": ">=8" } }, + "node_modules/text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -5665,6 +5874,14 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, + "node_modules/triple-beam": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/ts-api-utils": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", @@ -5925,6 +6142,66 @@ "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", "dev": true }, + "node_modules/winston": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.11.0.tgz", + "integrity": "sha512-L3yR6/MzZAOl0DsysUXHVjOwv8mKZ71TrA/41EIduGpOOV5LQVodqN+QdQ6BS6PJ/RdIshZhq84P/fStEZkk7g==", + "dependencies": { + "@colors/colors": "^1.6.0", + "@dabh/diagnostics": "^2.0.2", + "async": "^3.2.3", + "is-stream": "^2.0.0", + "logform": "^2.4.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "safe-stable-stringify": "^2.3.1", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.5.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-transport": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.6.0.tgz", + "integrity": "sha512-wbBA9PbPAHxKiygo7ub7BYRiKxms0tpfU2ljtWzb3SjRjv5yl6Ozuy/TkXf00HTAt+Uylo3gSkNwzc4ME0wiIg==", + "dependencies": { + "logform": "^2.3.2", + "readable-stream": "^3.6.0", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-transport/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/winston/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/wollok-ts": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/wollok-ts/-/wollok-ts-4.0.6.tgz", @@ -5957,6 +6234,25 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/wrappy": { "version": "1.0.2", "license": "ISC" @@ -6603,6 +6899,11 @@ "to-fast-properties": "^2.0.0" } }, + "@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==" + }, "@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -6624,6 +6925,16 @@ } } }, + "@dabh/diagnostics": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "requires": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, "@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -7067,6 +7378,11 @@ "@types/node": "*" } }, + "@types/triple-beam": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", + "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" + }, "@typescript-eslint/eslint-plugin": { "version": "6.9.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.1.tgz", @@ -7229,9 +7545,6 @@ "version": "4.1.1", "dev": true }, - "ansi-regex": { - "version": "5.0.1" - }, "ansi-styles": { "version": "4.3.0", "requires": { @@ -7287,6 +7600,11 @@ "version": "1.1.0", "dev": true }, + "async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -7560,6 +7878,45 @@ "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "requires": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + }, + "dependencies": { + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + } } }, "color-convert": { @@ -7571,6 +7928,24 @@ "color-name": { "version": "1.1.4" }, + "color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "colorspace": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "requires": { + "color": "^3.1.3", + "text-hex": "1.0.x" + } + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -7782,6 +8157,11 @@ "emoji-regex": { "version": "8.0.0" }, + "enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, "encodeurl": { "version": "1.0.2" }, @@ -7902,6 +8282,23 @@ "optionator": "^0.9.3", "strip-ansi": "^6.0.1", "text-table": "^0.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } } }, "eslint-scope": { @@ -8079,6 +8476,11 @@ "reusify": "^1.0.4" } }, + "fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -8157,6 +8559,11 @@ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, + "fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, "foreground-child": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", @@ -8494,6 +8901,11 @@ "ipaddr.js": { "version": "1.9.1" }, + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "is-binary-path": { "version": "2.1.0", "dev": true, @@ -8546,8 +8958,7 @@ "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" }, "is-typedarray": { "version": "1.0.0", @@ -8738,6 +9149,11 @@ "json-buffer": "3.0.1" } }, + "kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -8784,6 +9200,19 @@ "is-unicode-supported": "^0.1.0" } }, + "logform": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz", + "integrity": "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==", + "requires": { + "@colors/colors": "1.6.0", + "@types/triple-beam": "^1.3.2", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + } + }, "loglevel": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.1.tgz", @@ -9109,6 +9538,12 @@ "yargs": "^15.0.2" }, "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -9175,6 +9610,15 @@ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -9243,6 +9687,14 @@ "wrappy": "1" } }, + "one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "requires": { + "fn.name": "1.x.x" + } + }, "optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -9698,6 +10150,11 @@ "safe-buffer": { "version": "5.1.2" }, + "safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==" + }, "safer-buffer": { "version": "2.1.2" }, @@ -9846,6 +10303,14 @@ "simple-concat": "^1.0.0" } }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "requires": { + "is-arrayish": "^0.3.1" + } + }, "sinon": { "version": "17.0.1", "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", @@ -9929,6 +10394,11 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==" + }, "statuses": { "version": "2.0.1" }, @@ -9952,12 +10422,21 @@ "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "requires": { - "ansi-regex": "^5.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + } } }, "strip-bom": { @@ -10062,6 +10541,11 @@ "minimatch": "^3.0.4" } }, + "text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -10087,6 +10571,11 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, + "triple-beam": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==" + }, "ts-api-utils": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", @@ -10243,6 +10732,58 @@ "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", "dev": true }, + "winston": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.11.0.tgz", + "integrity": "sha512-L3yR6/MzZAOl0DsysUXHVjOwv8mKZ71TrA/41EIduGpOOV5LQVodqN+QdQ6BS6PJ/RdIshZhq84P/fStEZkk7g==", + "requires": { + "@colors/colors": "^1.6.0", + "@dabh/diagnostics": "^2.0.2", + "async": "^3.2.3", + "is-stream": "^2.0.0", + "logform": "^2.4.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "safe-stable-stringify": "^2.3.1", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.5.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "winston-transport": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.6.0.tgz", + "integrity": "sha512-wbBA9PbPAHxKiygo7ub7BYRiKxms0tpfU2ljtWzb3SjRjv5yl6Ozuy/TkXf00HTAt+Uylo3gSkNwzc4ME0wiIg==", + "requires": { + "logform": "^2.3.2", + "readable-stream": "^3.6.0", + "triple-beam": "^1.3.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "wollok-ts": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/wollok-ts/-/wollok-ts-4.0.6.tgz", @@ -10265,6 +10806,21 @@ "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + } } }, "wrappy": { diff --git a/package.json b/package.json index aa247b6..6e7ed89 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "p5": "^1.8.0", "pkg": "^5.8.1", "socket.io": "^4.5.1", + "winston": "^3.11.0", "wollok-ts": "4.0.6" }, "devDependencies": { diff --git a/src/commands/test.ts b/src/commands/test.ts index e725ac2..b93e587 100644 --- a/src/commands/test.ts +++ b/src/commands/test.ts @@ -5,7 +5,9 @@ import { Entity, Environment, Node, Test } from 'wollok-ts' import { is, match, when } from 'wollok-ts/dist/extensions' import interpret from 'wollok-ts/dist/interpreter/interpreter' import natives from 'wollok-ts/dist/wre/wre.natives' -import { buildEnvironmentForProject, failureDescription, successDescription, valueDescription, validateEnvironment, handleError, ENTER } from '../utils' +import { buildEnvironmentForProject, failureDescription, successDescription, valueDescription, validateEnvironment, handleError, ENTER, stackTrace } from '../utils' +import { logger as fileLogger } from '../logger' +import { TimeMeasurer } from '../time-measurer' const { log } = console @@ -42,9 +44,11 @@ export default async function (filter: string | undefined, options: Options): Pr try { validateParameters(filter, options) + const timeMeasurer = new TimeMeasurer() const { project, skipValidations } = options - logger.info(`Running all tests ${filter ? `matching ${valueDescription(filter)} ` : ''}on ${valueDescription(project)}`) + const runAllTestsDescription = `๐Ÿงช Running all tests ${filter ? `matching ${valueDescription(filter)} ` : ''}on ${valueDescription(project)}` + logger.info(runAllTestsDescription) const environment = await buildEnvironmentForProject(project) validateEnvironment(environment, skipValidations) @@ -91,6 +95,12 @@ export default async function (filter: string | undefined, options: Options): Pr logger.error(failureDescription(bold(test.fullyQualifiedName), error)) }) + const failuresForLogging = failures.map(([test, error]) => ({ + test: test.fullyQualifiedName, + error: stackTrace(error), + })) + fileLogger.info({ level: 'info', message: `๐Ÿงช Test runner executed ${filter ? `matching ${filter} ` : ''}on ${project}`, result: { ok: successes, failed: failures.length }, failures: failuresForLogging, timeElapsed: timeMeasurer.elapsedTime() }) + logger.info( ENTER, successDescription(`${successes} passing`), diff --git a/src/logger.ts b/src/logger.ts new file mode 100644 index 0000000..d960748 --- /dev/null +++ b/src/logger.ts @@ -0,0 +1,15 @@ +import winston, { format } from 'winston' + +export const logger = winston.createLogger({ + transports: [ + new winston.transports.File( + { + filename: 'wollok.log', + format: format.combine( + format.timestamp(), + format.json(), + ), + }, + ), + ], +}) \ No newline at end of file diff --git a/src/time-measurer.ts b/src/time-measurer.ts new file mode 100644 index 0000000..c58efbe --- /dev/null +++ b/src/time-measurer.ts @@ -0,0 +1,15 @@ +export class TimeMeasurer { + private initialTime: number = this.now() + + private now(): number { + return this.getTime(process.hrtime.bigint()) + } + + private getTime(value: bigint): number { + return Number(value / BigInt(1000000)) + } + + public elapsedTime(): number { + return this.now() - this.initialTime + } +} \ No newline at end of file diff --git a/src/utils.ts b/src/utils.ts index efcbf08..5560b83 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -87,7 +87,7 @@ export const valueDescription = (val: any): string => italic(blue(val)) export const successDescription = (description: string): string => green(`${bold('โœ“')} ${description}`) -export const failureDescription = (description: string, e?: Error): string => { +export const stackTrace = (e?: Error): string => { const indexOfTsStack = e?.stack?.indexOf(WOLLOK_EXTRA_STACK_TRACE_HEADER) const fullStack = e?.stack?.slice(0, indexOfTsStack ?? -1) ?? '' @@ -97,9 +97,12 @@ export const failureDescription = (description: string, e?: Error): string => { .replaceAll(' ', ' ') .split('\n').join('\n ') - return red(`${bold('โœ—')} ${description}${stack ? '\n ' + stack : ''}`) + return stack ? '\n ' + stack : '' } +export const failureDescription = (description: string, e?: Error): string => + red(`${bold('โœ—')} ${description}${stackTrace(e)}`) + export const problemDescription = (problem: Problem): string => { const color = problem.level === 'warning' ? yellowBright : red const header = bold(`[${problem.level.toUpperCase()}]`) From dafaa982431d65060fd39b9f4cad2007beb70dd0 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Fri, 26 Jan 2024 20:40:18 -0300 Subject: [PATCH 02/15] Add logger for programs --- src/commands/run.ts | 23 +++++++++++++++++------ src/commands/test.ts | 2 +- src/utils.ts | 18 ++++++++++-------- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/commands/run.ts b/src/commands/run.ts index fd13023..8f99a16 100644 --- a/src/commands/run.ts +++ b/src/commands/run.ts @@ -1,3 +1,4 @@ +import { TimeMeasurer } from './../time-measurer' import { bold } from 'chalk' import cors from 'cors' import express from 'express' @@ -9,9 +10,10 @@ import { Server, Socket } from 'socket.io' import { Environment, link, Name, Package, parse, RuntimeObject, WollokException } from 'wollok-ts' import interpret, { Interpreter } from 'wollok-ts/dist/interpreter/interpreter' import natives from 'wollok-ts/dist/wre/wre.natives' -import { ENTER, buildEnvironmentForProject, failureDescription, handleError, isImageFile, publicPath, readPackageProperties, serverError, successDescription, validateEnvironment, valueDescription } from '../utils' +import { ENTER, buildEnvironmentForProject, failureDescription, handleError, isImageFile, publicPath, readPackageProperties, serverError, stackTrace, successDescription, validateEnvironment, valueDescription } from '../utils' import { buildKeyPressEvent, canvasResolution, Image, queueEvent, visualState, VisualState, wKeyCode } from './extrasGame' import { getDataDiagram } from '../services/diagram-generator' +import { logger as fileLogger } from '../logger' const { time, timeEnd } = console @@ -33,16 +35,19 @@ type DynamicDiagramClient = { onReload: () => void, } +const icon = '๐Ÿš€' + export default async function (programFQN: Name, options: Options): Promise { const { project, game } = options + const timeMeasurer = new TimeMeasurer() try { - logger.info(`Running ${valueDescription(programFQN)} ${runner(game)} on ${valueDescription(project)}`) + logger.info(`${icon} Running program ${valueDescription(programFQN)} ${runner(game)} on ${valueDescription(project)}`) options.assets = game ? getAssetsFolder(options) : '' if (game) { - logger.info(`Assets folder ${join(project, options.assets)}`) + logger.info(`๐Ÿ—‚๏ธ Assets folder ${join(project, options.assets)}`) } - logger.info(`Building environment for ${valueDescription(programFQN)}...${ENTER}`) + logger.info(`๐ŸŒ Building environment for ${valueDescription(programFQN)}...${ENTER}`) const environment = await buildEnvironmentForProgram(options) const debug = logger.getLevel() <= logger.levels.DEBUG if (debug) time(successDescription('Run initiated successfully')) @@ -59,10 +64,16 @@ export default async function (programFQN: Name, options: Options): Promise { logger.error(red(bold('๐Ÿ’ฅ Uh-oh... Unexpected Error!'))) - logger.error(red(error.message)) + logger.error(red(error.message.replaceAll(WOLLOK_EXTRA_STACK_TRACE_HEADER, ''))) logger.debug(failureDescription('โ„น๏ธ Stack trace:', error)) } @@ -87,21 +87,23 @@ export const valueDescription = (val: any): string => italic(blue(val)) export const successDescription = (description: string): string => green(`${bold('โœ“')} ${description}`) -export const stackTrace = (e?: Error): string => { +export const stackTrace = (e?: Error): string[] => { const indexOfTsStack = e?.stack?.indexOf(WOLLOK_EXTRA_STACK_TRACE_HEADER) const fullStack = e?.stack?.slice(0, indexOfTsStack ?? -1) ?? '' - const stack = fullStack + return fullStack .replaceAll('\t', ' ') .replaceAll(' ', ' ') .replaceAll(' ', ' ') - .split('\n').join('\n ') - - return stack ? '\n ' + stack : '' + .split('\n') + .filter(stackTraceElement => stackTraceElement.trim()) } -export const failureDescription = (description: string, e?: Error): string => - red(`${bold('โœ—')} ${description}${stackTrace(e)}`) +export const failureDescription = (description: string, e?: Error): string => { + const stack = stackTrace(e).join('\n ') + const stackTraceSanitized = stack ? '\n ' + stack : '' + return red(`${bold('โœ—')} ${description}${stackTraceSanitized}`) +} export const problemDescription = (problem: Problem): string => { const color = problem.level === 'warning' ? yellowBright : red From 298b9a63b27b165e3074197ff9fdae5fd68ac632 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sat, 27 Jan 2024 09:57:26 -0300 Subject: [PATCH 03/15] Fix tests --- test/repl.test.ts | 7 ++----- wollok.log | 10 ++++++++++ 2 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 wollok.log diff --git a/test/repl.test.ts b/test/repl.test.ts index f5564c5..b32aabd 100644 --- a/test/repl.test.ts +++ b/test/repl.test.ts @@ -182,11 +182,10 @@ describe('REPL', () => { it('should show only custom stack trace elements when an error occurs (with a file)', async () => { const result = interprete(interpreter, 'pepitaRota.vola(10)') const stackTrace = result.split('\n') - stackTrace.length.should.equal(4) + stackTrace.length.should.equal(3) consoleCharacters(stackTrace[0]).should.be.equal('โœ— Evaluation Error!') consoleCharacters(stackTrace[1]).should.be.equal('wollok.lang.EvaluationError wrapping TypeScript TypeError: Expected an instance of wollok.lang.Number but got a wollok.lang.String instead') consoleCharacters(stackTrace[2]).should.be.equal('at aves.pepitaRota.vola(distancia) [aves.wlk:22]') - consoleCharacters(stackTrace[3]).should.be.equal('') }) describe('in a sub-folder', () => { @@ -233,11 +232,9 @@ describe('REPL', () => { it('should show only custom stack trace elements when an error occurs (without a file)', async () => { const result = interprete(interpreter, 'assert.equals(2, 1)') const stackTrace = result.split('\n') - stackTrace.length.should.equal(4) + stackTrace.length.should.equal(2) consoleCharacters(stackTrace[0]).should.be.equal('โœ— Evaluation Error!') consoleCharacters(stackTrace[1]).should.be.equal('wollok.lib.AssertionException: Expected <2> but found <1>') - consoleCharacters(stackTrace[2]).should.be.equal('') - consoleCharacters(stackTrace[3]).should.be.equal('') }) }) diff --git a/wollok.log b/wollok.log new file mode 100644 index 0000000..6dd8369 --- /dev/null +++ b/wollok.log @@ -0,0 +1,10 @@ +{"failures":[],"level":"info","message":"๐Ÿงช Test runner executed on examples/init-examples/basic-example","result":{"failed":0,"ok":1},"timeElapsed":897,"timestamp":"2024-01-27T12:53:22.782Z"} +{"level":"info","message":"๐Ÿš€ Program executed mainExample.PepitaProgram on examples/run-examples/basic-example","ok":true,"timeElapsed":596,"timestamp":"2024-01-27T12:53:23.506Z"} +{"error":["Error: Fatal error while running validations. Aborting run due to validation errors!"," at validateEnvironment (/home/dodain/workspace/wollok-dev/wollok-ts-cli/src/utils.ts:70:13)"," at buildEnvironmentForProgram (/home/dodain/workspace/wollok-dev/wollok-ts-cli/src/commands/run.ts:262:22)"," at async default_1 (/home/dodain/workspace/wollok-dev/wollok-ts-cli/src/commands/run.ts:51:25)"," at async Context. (/home/dodain/workspace/wollok-dev/wollok-ts-cli/test/run.test.ts:178:7"],"level":"info","message":"๐Ÿš€ Program executed mainExample.PepitaProgram on examples/run-examples/bad-example","ok":false,"timeElapsed":627,"timestamp":"2024-01-27T12:53:24.138Z"} +{"failures":[],"level":"info","message":"๐Ÿงช Test runner executed on examples/test-examples/normal-case","result":{"failed":0,"ok":2},"timeElapsed":254,"timestamp":"2024-01-27T12:53:26.335Z"} +{"failures":[{"error":["wollok.lib.AssertionException: Expected <2> but found <1>"," at test-two.\"third describe\".\"just a test\" [test-two.wtest:15]"],"test":"test-two.\"third describe\".\"just a test\""}],"level":"info","message":"๐Ÿงช Test runner executed on examples/test-examples/normal-case","result":{"failed":1,"ok":4},"timeElapsed":223,"timestamp":"2024-01-27T12:53:26.562Z"} +{"failures":[],"level":"info","message":"๐Ÿงช Test runner executed on examples/init-examples/basic-example","result":{"failed":0,"ok":1},"timeElapsed":1002,"timestamp":"2024-01-27T12:57:00.341Z"} +{"level":"info","message":"๐Ÿš€ Program executed mainExample.PepitaProgram on examples/run-examples/basic-example","ok":true,"timeElapsed":688,"timestamp":"2024-01-27T12:57:01.143Z"} +{"error":["Error: Fatal error while running validations. Aborting run due to validation errors!"," at validateEnvironment (/home/dodain/workspace/wollok-dev/wollok-ts-cli/src/utils.ts:70:13)"," at buildEnvironmentForProgram (/home/dodain/workspace/wollok-dev/wollok-ts-cli/src/commands/run.ts:262:22)"," at async default_1 (/home/dodain/workspace/wollok-dev/wollok-ts-cli/src/commands/run.ts:51:25)"," at async Context. (/home/dodain/workspace/wollok-dev/wollok-ts-cli/test/run.test.ts:178:7"],"level":"info","message":"๐Ÿš€ Program executed mainExample.PepitaProgram on examples/run-examples/bad-example","ok":false,"timeElapsed":639,"timestamp":"2024-01-27T12:57:01.787Z"} +{"failures":[],"level":"info","message":"๐Ÿงช Test runner executed on examples/test-examples/normal-case","result":{"failed":0,"ok":2},"timeElapsed":223,"timestamp":"2024-01-27T12:57:03.958Z"} +{"failures":[{"error":["wollok.lib.AssertionException: Expected <2> but found <1>"," at test-two.\"third describe\".\"just a test\" [test-two.wtest:15]"],"test":"test-two.\"third describe\".\"just a test\""}],"level":"info","message":"๐Ÿงช Test runner executed on examples/test-examples/normal-case","result":{"failed":1,"ok":4},"timeElapsed":228,"timestamp":"2024-01-27T12:57:04.188Z"} From 96b313ee026c9951c8ec4f3ef00a24608c4dc731 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sat, 27 Jan 2024 10:22:37 -0300 Subject: [PATCH 04/15] Deleting wollok.log generated by tests --- wollok.log | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 wollok.log diff --git a/wollok.log b/wollok.log deleted file mode 100644 index 6dd8369..0000000 --- a/wollok.log +++ /dev/null @@ -1,10 +0,0 @@ -{"failures":[],"level":"info","message":"๐Ÿงช Test runner executed on examples/init-examples/basic-example","result":{"failed":0,"ok":1},"timeElapsed":897,"timestamp":"2024-01-27T12:53:22.782Z"} -{"level":"info","message":"๐Ÿš€ Program executed mainExample.PepitaProgram on examples/run-examples/basic-example","ok":true,"timeElapsed":596,"timestamp":"2024-01-27T12:53:23.506Z"} -{"error":["Error: Fatal error while running validations. Aborting run due to validation errors!"," at validateEnvironment (/home/dodain/workspace/wollok-dev/wollok-ts-cli/src/utils.ts:70:13)"," at buildEnvironmentForProgram (/home/dodain/workspace/wollok-dev/wollok-ts-cli/src/commands/run.ts:262:22)"," at async default_1 (/home/dodain/workspace/wollok-dev/wollok-ts-cli/src/commands/run.ts:51:25)"," at async Context. (/home/dodain/workspace/wollok-dev/wollok-ts-cli/test/run.test.ts:178:7"],"level":"info","message":"๐Ÿš€ Program executed mainExample.PepitaProgram on examples/run-examples/bad-example","ok":false,"timeElapsed":627,"timestamp":"2024-01-27T12:53:24.138Z"} -{"failures":[],"level":"info","message":"๐Ÿงช Test runner executed on examples/test-examples/normal-case","result":{"failed":0,"ok":2},"timeElapsed":254,"timestamp":"2024-01-27T12:53:26.335Z"} -{"failures":[{"error":["wollok.lib.AssertionException: Expected <2> but found <1>"," at test-two.\"third describe\".\"just a test\" [test-two.wtest:15]"],"test":"test-two.\"third describe\".\"just a test\""}],"level":"info","message":"๐Ÿงช Test runner executed on examples/test-examples/normal-case","result":{"failed":1,"ok":4},"timeElapsed":223,"timestamp":"2024-01-27T12:53:26.562Z"} -{"failures":[],"level":"info","message":"๐Ÿงช Test runner executed on examples/init-examples/basic-example","result":{"failed":0,"ok":1},"timeElapsed":1002,"timestamp":"2024-01-27T12:57:00.341Z"} -{"level":"info","message":"๐Ÿš€ Program executed mainExample.PepitaProgram on examples/run-examples/basic-example","ok":true,"timeElapsed":688,"timestamp":"2024-01-27T12:57:01.143Z"} -{"error":["Error: Fatal error while running validations. Aborting run due to validation errors!"," at validateEnvironment (/home/dodain/workspace/wollok-dev/wollok-ts-cli/src/utils.ts:70:13)"," at buildEnvironmentForProgram (/home/dodain/workspace/wollok-dev/wollok-ts-cli/src/commands/run.ts:262:22)"," at async default_1 (/home/dodain/workspace/wollok-dev/wollok-ts-cli/src/commands/run.ts:51:25)"," at async Context. (/home/dodain/workspace/wollok-dev/wollok-ts-cli/test/run.test.ts:178:7"],"level":"info","message":"๐Ÿš€ Program executed mainExample.PepitaProgram on examples/run-examples/bad-example","ok":false,"timeElapsed":639,"timestamp":"2024-01-27T12:57:01.787Z"} -{"failures":[],"level":"info","message":"๐Ÿงช Test runner executed on examples/test-examples/normal-case","result":{"failed":0,"ok":2},"timeElapsed":223,"timestamp":"2024-01-27T12:57:03.958Z"} -{"failures":[{"error":["wollok.lib.AssertionException: Expected <2> but found <1>"," at test-two.\"third describe\".\"just a test\" [test-two.wtest:15]"],"test":"test-two.\"third describe\".\"just a test\""}],"level":"info","message":"๐Ÿงช Test runner executed on examples/test-examples/normal-case","result":{"failed":1,"ok":4},"timeElapsed":228,"timestamp":"2024-01-27T12:57:04.188Z"} From 90bc2e8e20c76a32ef970cca349427539451b1d7 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sat, 27 Jan 2024 10:24:02 -0300 Subject: [PATCH 05/15] Ignoring wollok.log from tests --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index f1273b9..cf21122 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,5 @@ src/wre/wre.json .nyc_output coverage .DS_Store -/public/diagram/lib/* \ No newline at end of file +/public/diagram/lib/* +wollok.log \ No newline at end of file From 9ed2529f530031ba1d8bd8693ba0950cb74dbc3a Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 28 Jan 2024 00:15:40 -0300 Subject: [PATCH 06/15] Add logger to games --- src/commands/run.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/commands/run.ts b/src/commands/run.ts index 8f99a16..9b52a61 100644 --- a/src/commands/run.ts +++ b/src/commands/run.ts @@ -35,16 +35,24 @@ type DynamicDiagramClient = { onReload: () => void, } -const icon = '๐Ÿš€' +const programIcon = '๐Ÿš€' +const gameIcon = '๐Ÿ‘พ' export default async function (programFQN: Name, options: Options): Promise { const { project, game } = options const timeMeasurer = new TimeMeasurer() try { - logger.info(`${icon} Running program ${valueDescription(programFQN)} ${runner(game)} on ${valueDescription(project)}`) + logger.info(`${programIcon} Running program ${valueDescription(programFQN)} ${runner(game)} on ${valueDescription(project)}`) options.assets = game ? getAssetsFolder(options) : '' if (game) { - logger.info(`๐Ÿ—‚๏ธ Assets folder ${join(project, options.assets)}`) + const logGameFinished = (exitCode: any) => { + fileLogger.info({ message: `${gameIcon} Game executed ${programFQN} on ${project}`, timeElapsed: timeMeasurer.elapsedTime(), exitCode }) + process.exit(exitCode) + } + logger.info(`๐Ÿ—‚๏ธ Assets folder ${join(project, options.assets)}`) + Array.from(['exit', 'SIGINT', 'SIGUSR1', 'SIGUSR2', 'SIGTERM', 'SIGHUP', 'uncaughtException']).forEach((eventType: string) => { + process.on(eventType, logGameFinished) + }) } logger.info(`๐ŸŒ Building environment for ${valueDescription(programFQN)}...${ENTER}`) @@ -65,13 +73,13 @@ export default async function (programFQN: Name, options: Options): Promise Date: Sun, 28 Jan 2024 00:27:10 -0300 Subject: [PATCH 07/15] Unifying icons for logging --- src/commands/run.ts | 11 ++++------- src/commands/test.ts | 6 ++++-- src/utils.ts | 9 +++++++++ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/commands/run.ts b/src/commands/run.ts index 9b52a61..b898ee7 100644 --- a/src/commands/run.ts +++ b/src/commands/run.ts @@ -10,7 +10,7 @@ import { Server, Socket } from 'socket.io' import { Environment, link, Name, Package, parse, RuntimeObject, WollokException } from 'wollok-ts' import interpret, { Interpreter } from 'wollok-ts/dist/interpreter/interpreter' import natives from 'wollok-ts/dist/wre/wre.natives' -import { ENTER, buildEnvironmentForProject, failureDescription, handleError, isImageFile, publicPath, readPackageProperties, serverError, stackTrace, successDescription, validateEnvironment, valueDescription } from '../utils' +import { ENTER, buildEnvironmentForProject, buildEnvironmentIcon, failureDescription, folderIcon, gameIcon, handleError, isImageFile, programIcon, publicPath, readPackageProperties, serverError, stackTrace, successDescription, validateEnvironment, valueDescription } from '../utils' import { buildKeyPressEvent, canvasResolution, Image, queueEvent, visualState, VisualState, wKeyCode } from './extrasGame' import { getDataDiagram } from '../services/diagram-generator' import { logger as fileLogger } from '../logger' @@ -35,27 +35,24 @@ type DynamicDiagramClient = { onReload: () => void, } -const programIcon = '๐Ÿš€' -const gameIcon = '๐Ÿ‘พ' - export default async function (programFQN: Name, options: Options): Promise { const { project, game } = options const timeMeasurer = new TimeMeasurer() try { - logger.info(`${programIcon} Running program ${valueDescription(programFQN)} ${runner(game)} on ${valueDescription(project)}`) + logger.info(`${game ? gameIcon : programIcon} Running program ${valueDescription(programFQN)} ${runner(game)} on ${valueDescription(project)}`) options.assets = game ? getAssetsFolder(options) : '' if (game) { const logGameFinished = (exitCode: any) => { fileLogger.info({ message: `${gameIcon} Game executed ${programFQN} on ${project}`, timeElapsed: timeMeasurer.elapsedTime(), exitCode }) process.exit(exitCode) } - logger.info(`๐Ÿ—‚๏ธ Assets folder ${join(project, options.assets)}`) + logger.info(`${folderIcon} Assets folder ${join(project, options.assets)}`) Array.from(['exit', 'SIGINT', 'SIGUSR1', 'SIGUSR2', 'SIGTERM', 'SIGHUP', 'uncaughtException']).forEach((eventType: string) => { process.on(eventType, logGameFinished) }) } - logger.info(`๐ŸŒ Building environment for ${valueDescription(programFQN)}...${ENTER}`) + logger.info(`${buildEnvironmentIcon} Building environment for ${valueDescription(programFQN)}...${ENTER}`) const environment = await buildEnvironmentForProgram(options) const debug = logger.getLevel() <= logger.levels.DEBUG if (debug) time(successDescription('Run initiated successfully')) diff --git a/src/commands/test.ts b/src/commands/test.ts index a0dacc9..5963022 100644 --- a/src/commands/test.ts +++ b/src/commands/test.ts @@ -5,7 +5,7 @@ import { Entity, Environment, Node, Test } from 'wollok-ts' import { is, match, when } from 'wollok-ts/dist/extensions' import interpret from 'wollok-ts/dist/interpreter/interpreter' import natives from 'wollok-ts/dist/wre/wre.natives' -import { buildEnvironmentForProject, failureDescription, successDescription, valueDescription, validateEnvironment, handleError, ENTER, stackTrace } from '../utils' +import { buildEnvironmentForProject, failureDescription, successDescription, valueDescription, validateEnvironment, handleError, ENTER, stackTrace, buildEnvironmentIcon, testIcon } from '../utils' import { logger as fileLogger } from '../logger' import { TimeMeasurer } from '../time-measurer' @@ -46,9 +46,11 @@ export default async function (filter: string | undefined, options: Options): Pr const timeMeasurer = new TimeMeasurer() const { project, skipValidations } = options - const runAllTestsDescription = `๐Ÿงช Running all tests ${filter ? `matching ${valueDescription(filter)} ` : ''}on ${valueDescription(project)}` + const runAllTestsDescription = `${testIcon} Running all tests ${filter ? `matching ${valueDescription(filter)} ` : ''}on ${valueDescription(project)}` logger.info(runAllTestsDescription) + + logger.info(`${buildEnvironmentIcon} Building environment for ${valueDescription(project)}...${ENTER}`) const environment = await buildEnvironmentForProject(project) validateEnvironment(environment, skipValidations) diff --git a/src/utils.ts b/src/utils.ts index e08c455..4c21c07 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -13,6 +13,15 @@ const { time, timeEnd } = console export const ENTER = '\n' +// โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• +// ICONS +// โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• +export const programIcon = '๐Ÿš€' +export const gameIcon = '๐Ÿ‘พ' +export const testIcon = '๐Ÿงช' +export const buildEnvironmentIcon = '๐ŸŒ' +export const folderIcon = '๐Ÿ—‚๏ธ' + // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• // FILE / PATH HANDLING // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• From 6e895c3a9a3f77a5a510f532d502f05d3e6357e1 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 28 Jan 2024 09:52:25 -0300 Subject: [PATCH 08/15] Add time measurer test --- test/time-measurer.test.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 test/time-measurer.test.ts diff --git a/test/time-measurer.test.ts b/test/time-measurer.test.ts new file mode 100644 index 0000000..b1e0ab6 --- /dev/null +++ b/test/time-measurer.test.ts @@ -0,0 +1,25 @@ +import { expect, should } from 'chai' +import sinon from 'sinon' +import { TimeMeasurer } from '../src/time-measurer' + +should() + +describe('Time Measurer', () => { + + let clock: sinon.SinonFakeTimers + + beforeEach(async () => { + clock = sinon.useFakeTimers() + }) + + afterEach(() => { + sinon.restore() + }) + + it('time elapsed is calculated based on hrtime', () => { + const timeMeasurer = new TimeMeasurer() + clock.tick(2000) + expect(timeMeasurer.elapsedTime()).to.equal(2000) + }) + +}) \ No newline at end of file From 04c19d4112b35d417b10183f027f84f90888d666 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 28 Jan 2024 12:21:12 -0300 Subject: [PATCH 09/15] add tests for logger in test runner --- test/test.test.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/test.test.ts b/test/test.test.ts index 9c004b0..02fa1a2 100644 --- a/test/test.test.ts +++ b/test/test.test.ts @@ -4,6 +4,7 @@ import { buildEnvironmentForProject } from '../src/utils' import test, { getTarget, sanitize, tabulationForNode, validateParameters } from '../src/commands/test' import { Environment } from 'wollok-ts' import logger from 'loglevel' +import { logger as fileLogger } from '../src/logger' import sinon from 'sinon' import { spyCalledWithSubstring } from './assertions' @@ -251,6 +252,7 @@ describe('Test', () => { describe('smoke test for test default function', () => { + let fileLoggerInfoSpy: sinon.SinonStub let loggerInfoSpy: sinon.SinonStub let processExitSpy: sinon.SinonStub @@ -266,6 +268,7 @@ describe('Test', () => { beforeEach(() => { loggerInfoSpy = sinon.stub(logger, 'info') + fileLoggerInfoSpy = sinon.stub(fileLogger, 'info') processExitSpy = sinon.stub(process, 'exit') }) @@ -283,6 +286,8 @@ describe('Test', () => { expect(spyCalledWithSubstring(loggerInfoSpy, 'Running 2 tests')).to.be.true expect(spyCalledWithSubstring(loggerInfoSpy, '2 passing')).to.be.true expect(spyCalledWithSubstring(loggerInfoSpy, '0 failing')).to.be.false // old version + expect(fileLoggerInfoSpy.calledOnce).to.be.true + expect(fileLoggerInfoSpy.firstCall.firstArg.result).to.deep.equal({ ok: 2, failed: 0 }) }) it('returns exit code 2 if one or more tests fail', async () => { @@ -292,6 +297,10 @@ describe('Test', () => { expect(spyCalledWithSubstring(loggerInfoSpy, 'Running 5 tests')).to.be.true expect(spyCalledWithSubstring(loggerInfoSpy, '4 passing')).to.be.true expect(spyCalledWithSubstring(loggerInfoSpy, '1 failing')).to.be.true + expect(fileLoggerInfoSpy.calledOnce).to.be.true + const fileLoggerArg = fileLoggerInfoSpy.firstCall.firstArg + expect(fileLoggerArg.result).to.deep.equal({ ok: 4, failed: 1 }) + expect(fileLoggerArg.failures.length).to.equal(1) }) it('returns exit code 1 if tests throw an error', async () => { From 0279e3044ca22a3894689892f69c5c4c3d3402e6 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 28 Jan 2024 15:00:29 -0300 Subject: [PATCH 10/15] Log REPL errors on file --- src/commands/repl.ts | 6 +++++- src/utils.ts | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/commands/repl.ts b/src/commands/repl.ts index 2016373..871f150 100644 --- a/src/commands/repl.ts +++ b/src/commands/repl.ts @@ -14,7 +14,9 @@ import link from 'wollok-ts/dist/linker' import { ParseError } from 'wollok-ts/dist/parser' import natives from 'wollok-ts/dist/wre/wre.natives' import { getDataDiagram } from '../services/diagram-generator' -import { buildEnvironmentForProject, failureDescription, getFQN, linkSentence, publicPath, successDescription, valueDescription, validateEnvironment, handleError, ENTER, serverError } from '../utils' +import { buildEnvironmentForProject, failureDescription, getFQN, linkSentence, publicPath, successDescription, valueDescription, validateEnvironment, handleError, ENTER, serverError, stackTrace, replIcon } from '../utils' +import { logger as fileLogger } from '../logger' +import { TimeMeasurer } from '../time-measurer' export const REPL = 'REPL' @@ -107,6 +109,7 @@ export async function replFn(autoImportPath: string | undefined, options: Option export async function initializeInterpreter(autoImportPath: string | undefined, { project, skipValidations }: Options): Promise { let environment: Environment + const timeMeasurer = new TimeMeasurer() try { environment = await buildEnvironmentForProject(project) @@ -129,6 +132,7 @@ export async function initializeInterpreter(autoImportPath: string | undefined, return new Interpreter(Evaluation.build(environment, natives)) } catch (error: any) { handleError(error) + fileLogger.info({ message: `${replIcon} REPL execution - build failed for ${project}`, timeElapsed: timeMeasurer.elapsedTime(), ok: false, error: stackTrace(error) }) return process.exit(12) } } diff --git a/src/utils.ts b/src/utils.ts index 4c21c07..f26c971 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -19,6 +19,7 @@ export const ENTER = '\n' export const programIcon = '๐Ÿš€' export const gameIcon = '๐Ÿ‘พ' export const testIcon = '๐Ÿงช' +export const replIcon = '๐Ÿ–ฅ๏ธ' export const buildEnvironmentIcon = '๐ŸŒ' export const folderIcon = '๐Ÿ—‚๏ธ' From 35c5d12bf74d26f36a8bbc8e63e1425d59c07fe9 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 28 Jan 2024 15:06:42 -0300 Subject: [PATCH 11/15] Enhancing repl icon in common logger --- src/commands/repl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/repl.ts b/src/commands/repl.ts index 871f150..2d8dde6 100644 --- a/src/commands/repl.ts +++ b/src/commands/repl.ts @@ -45,7 +45,7 @@ export default async function (autoImportPath: string | undefined, options: Opti const history: string[] = [] export async function replFn(autoImportPath: string | undefined, options: Options): Promise { - logger.info(`Initializing Wollok REPL ${autoImportPath ? `for file ${valueDescription(autoImportPath)} ` : ''}on ${valueDescription(options.project)}`) + logger.info(`${replIcon} Initializing Wollok REPL ${autoImportPath ? `for file ${valueDescription(autoImportPath)} ` : ''}on ${valueDescription(options.project)}`) let interpreter = await initializeInterpreter(autoImportPath, options) const autoImportName = autoImportPath && replNode(interpreter.evaluation.environment).name From aca14ab0671b10472b96caaf43c7e7c3f61ffef8 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 28 Jan 2024 23:02:32 -0300 Subject: [PATCH 12/15] Add logger tests for programs --- test/run.test.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/run.test.ts b/test/run.test.ts index fa3b4b7..881a8ce 100644 --- a/test/run.test.ts +++ b/test/run.test.ts @@ -4,6 +4,7 @@ import { join } from 'path' import sinon from 'sinon' import run, { buildEnvironmentForProgram, getAssetsFolder, getGameInterpreter, getImages, getSoundsFolder, getVisuals, initializeGameClient } from '../src/commands/run' import { spyCalledWithSubstring } from './assertions' +import { logger as fileLogger } from '../src/logger' chai.should() const expect = chai.expect @@ -148,10 +149,12 @@ describe('testing run', () => { let processExitSpy: sinon.SinonStub let consoleLogSpy: sinon.SinonStub + let fileLoggerInfoSpy: sinon.SinonStub beforeEach(() => { processExitSpy = sinon.stub(process, 'exit') consoleLogSpy = sinon.stub(console, 'log') + fileLoggerInfoSpy = sinon.stub(fileLogger, 'info') }) afterEach(() => { @@ -172,6 +175,10 @@ describe('testing run', () => { expect(spyCalledWithSubstring(consoleLogSpy, 'Come')).to.be.true expect(spyCalledWithSubstring(consoleLogSpy, '290')).to.be.true expect(processExitSpy.calledWith(0)).to.be.true + expect(fileLoggerInfoSpy.calledOnce).to.be.true + const fileLoggerArg = fileLoggerInfoSpy.firstCall.firstArg + expect(fileLoggerArg.ok).to.be.true + expect(fileLoggerArg.message).to.contain('Program executed') }) it ('should exit if program has errors', async () => { @@ -182,6 +189,10 @@ describe('testing run', () => { startDiagram: false, }) expect(processExitSpy.calledWith(21)).to.be.true + expect(fileLoggerInfoSpy.calledOnce).to.be.true + const fileLoggerArg = fileLoggerInfoSpy.firstCall.firstArg + expect(fileLoggerArg.ok).to.be.false + expect(fileLoggerArg.error).to.be.ok }) }) From 7b9dbf117281135a33a123ec378551e80cc8b0e7 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Tue, 30 Jan 2024 21:39:43 -0300 Subject: [PATCH 13/15] Updating wollok-ts dependency --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 47957cf..8ed059b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,7 @@ "pkg": "^5.8.1", "socket.io": "^4.5.1", "winston": "^3.11.0", - "wollok-ts": "4.0.6" + "wollok-ts": "4.0.8" }, "bin": { "wollok": "build/src/index.js" @@ -6203,9 +6203,9 @@ } }, "node_modules/wollok-ts": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/wollok-ts/-/wollok-ts-4.0.6.tgz", - "integrity": "sha512-Ghsj21F9AZNgoJWaIGIGZf3vfpttgm9g+dPdyZBzEs02xPx2j6Z5CY7mUGUE9k1sJgrnETn4gWcNXsjGQnKuqQ==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/wollok-ts/-/wollok-ts-4.0.8.tgz", + "integrity": "sha512-EE24DPvGP20zTLFQgAG4vY8wIcuVay+gN0NeYtgyXl06Fwi6o98HUOSjEKP13AiAlAzkKq2MgF/4mfwaKoFm9w==", "dependencies": { "@types/parsimmon": "^1.10.8", "parsimmon": "^1.18.1", @@ -10785,9 +10785,9 @@ } }, "wollok-ts": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/wollok-ts/-/wollok-ts-4.0.6.tgz", - "integrity": "sha512-Ghsj21F9AZNgoJWaIGIGZf3vfpttgm9g+dPdyZBzEs02xPx2j6Z5CY7mUGUE9k1sJgrnETn4gWcNXsjGQnKuqQ==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/wollok-ts/-/wollok-ts-4.0.8.tgz", + "integrity": "sha512-EE24DPvGP20zTLFQgAG4vY8wIcuVay+gN0NeYtgyXl06Fwi6o98HUOSjEKP13AiAlAzkKq2MgF/4mfwaKoFm9w==", "requires": { "@types/parsimmon": "^1.10.8", "parsimmon": "^1.18.1", diff --git a/package.json b/package.json index 6e7ed89..e136649 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "pkg": "^5.8.1", "socket.io": "^4.5.1", "winston": "^3.11.0", - "wollok-ts": "4.0.6" + "wollok-ts": "4.0.8" }, "devDependencies": { "@types/chai": "^4.3.9", From 8a09c3d56b96000e2603ae19bec35b5916ac89b3 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Tue, 30 Jan 2024 21:40:08 -0300 Subject: [PATCH 14/15] Log file intro special folder --- src/logger.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/logger.ts b/src/logger.ts index d960748..d599a1e 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -4,7 +4,8 @@ export const logger = winston.createLogger({ transports: [ new winston.transports.File( { - filename: 'wollok.log', + filename: 'log/wollok.log', + maxsize: 1000000, format: format.combine( format.timestamp(), format.json(), From cd9d6325f832b1e4419a0b8269d225f61535178e Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Tue, 30 Jan 2024 21:53:23 -0300 Subject: [PATCH 15/15] Update src/commands/test.ts Co-authored-by: ivojawer --- src/commands/test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/test.ts b/src/commands/test.ts index 5963022..fdeb73c 100644 --- a/src/commands/test.ts +++ b/src/commands/test.ts @@ -101,7 +101,7 @@ export default async function (filter: string | undefined, options: Options): Pr test: test.fullyQualifiedName, error: stackTrace(error), })) - fileLogger.info({ message: `๐Ÿงช Test runner executed ${filter ? `matching ${filter} ` : ''}on ${project}`, result: { ok: successes, failed: failures.length }, failures: failuresForLogging, timeElapsed: timeMeasurer.elapsedTime() }) + fileLogger.info({ message: `${testIcon} Test runner executed ${filter ? `matching ${filter} ` : ''}on ${project}`, result: { ok: successes, failed: failures.length }, failures: failuresForLogging, timeElapsed: timeMeasurer.elapsedTime() }) logger.info( ENTER,