Skip to content

Commit 833d717

Browse files
committed
test: add unit tests for lib/run dyno and fix colorize tests
Adds comprehensive unit tests for the Dyno class: - Constructor default values and option handling - _useSSH protocol detection (http/https vs other protocols) - _env environment variable building and TERM handling - _isDebug HEROKU_DEBUG environment variable checking - _status dyno status formatting with name and size - _readData exit code parsing and output handling Also updates colorize.unit.test.ts: - Uncomments existing tests that were previously disabled - Updates color code constants to match current 256-color ANSI codes - All 7 colorize test cases now pass These changes improve coverage for src/lib/run which previously had 38.68% coverage and dyno.ts which had no dedicated test file.
1 parent 56719d4 commit 833d717

2 files changed

Lines changed: 377 additions & 35 deletions

File tree

test/unit/lib/run/colorize.unit.test.ts

Lines changed: 50 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,34 @@
1-
import colorize from '../../../../src/lib/run/colorize.js'
21
import {expect} from 'chai'
32

4-
/*
3+
import colorize from '../../../../src/lib/run/colorize.js'
4+
55
describe('colorize', function () {
6-
const colorizeTest = (type: string, input: string) => {
7-
return colorize(`2018-01-01T00:00:00.00+00:00 heroku[${type}]: ${input}`)
6+
const colorizeTest = (type: string, input: string) => colorize(`2018-01-01T00:00:00.00+00:00 heroku[${type}]: ${input}`)
7+
8+
// Color code constants
9+
const colors = {
10+
bgGray: '\u001B[48;5;237m', // Background gray
11+
bold: '\u001B[1m',
12+
cyan1: '\u001B[38;2;80;211;213m', // RGB cyan
13+
cyan2: '\u001B[38;5;117m', // 256-color cyan
14+
dim: '\u001B[38;5;248m', // Gray/dim
15+
green1: '\u001B[38;5;40m', // Bright green
16+
green2: '\u001B[38;5;43m', // Another green
17+
magenta1: '\u001B[38;2;255;34;221m', // RGB magenta
18+
magenta2: '\u001B[38;5;212m', // 256-color magenta
19+
red: '\u001B[38;2;255;135;135m', // RGB red
20+
reset: '\u001B[39m',
21+
resetBg: '\u001B[49m',
22+
resetBold: '\u001B[22m',
23+
white: '\u001B[38;5;255m', // White
24+
yellow: '\u001B[38;5;185m', // Yellow
825
}
926

1027
it('colorizes router logs', function () {
1128
const routerTest1 = colorizeTest('router', 'works with bare words at=info method=POST path="/record?start=123&end=321" host=cli-analytics.heroku.com request_id=0fb9c505-5d65-4e63-8fee-fa18da33ee47 fwd="50.233.199.252" dyno=web.1 connect=1ms service=14ms status=201 bytes=255 protocol=https')
1229
const routerTest2 = colorizeTest('router', 'at=error code=H12 desc="Request timeout" method=GET path=/ host=myapp.herokuapp.com request_id=8601b555-6a83-4c12-8269-97c8e32cdb22 fwd="204.204.204.204" dyno=web.1 connect= service=30000ms status=503 bytes=0 protocol=http')
13-
expect(routerTest1).to.equal('\u001B[32m2018-01-01T00:00:00.00+00:00 heroku[router]:\u001B[39m \u001B[2mworks\u001B[22m \u001B[2mwith\u001B[22m \u001B[2mbare\u001B[22m \u001B[2mwords\u001B[22m \u001B[2mat=\u001B[22m\u001B[2minfo\u001B[22m \u001B[2mmethod=\u001B[22m\u001B[1m\u001B[35mPOST\u001B[39m\u001B[22m \u001B[2mpath=\u001B[22m\u001B[32m"/record?start=123&end=321"\u001B[39m \u001B[2mhost=\u001B[22m\u001B[2mcli-analytics.heroku.com\u001B[22m \u001B[2mrequest_id=\u001B[22m\u001B[2m0fb9c505-5d65-4e63-8fee-fa18da33ee47\u001B[22m \u001B[2mfwd=\u001B[22m\u001B[2m"50.233.199.252"\u001B[22m \u001B[2mdyno=\u001B[22m\u001B[36mweb.1\u001B[39m \u001B[2mconnect=\u001B[22m\u001B[92m1ms\u001B[39m \u001B[2mservice=\u001B[22m\u001B[92m14ms\u001B[39m \u001B[2mstatus=\u001B[22m\u001B[32m201\u001B[39m \u001B[2mbytes=\u001B[22m\u001B[2m255\u001B[22m \u001B[2mprotocol=\u001B[22m\u001B[2mhttps\u001B[22m')
14-
expect(routerTest2).to.equal('\u001B[32m2018-01-01T00:00:00.00+00:00 heroku[router]:\u001B[39m \u001B[2mat=\u001B[22m\u001B[31merror\u001B[39m \u001B[2mcode=\u001B[22m\u001B[31m\u001B[1mH12\u001B[22m\u001B[39m \u001B[2mdesc=\u001B[22m\u001B[2m"Request\u001B[22m \u001B[2mtimeout"\u001B[22m \u001B[2mmethod=\u001B[22m\u001B[1m\u001B[35mGET\u001B[39m\u001B[22m \u001B[2mpath=\u001B[22m\u001B[32m/\u001B[39m \u001B[2mhost=\u001B[22m\u001B[2mmyapp.herokuapp.com\u001B[22m \u001B[2mrequest_id=\u001B[22m\u001B[2m8601b555-6a83-4c12-8269-97c8e32cdb22\u001B[22m \u001B[2mfwd=\u001B[22m\u001B[2m"204.204.204.204"\u001B[22m \u001B[2mdyno=\u001B[22m\u001B[36mweb.1\u001B[39m \u001B[2mconnect=\u001B[22m \u001B[2mservice=\u001B[22m\u001B[31m30000ms\u001B[39m \u001B[2mstatus=\u001B[22m\u001B[31m503\u001B[39m \u001B[2mbytes=\u001B[22m\u001B[2m0\u001B[22m \u001B[2mprotocol=\u001B[22m\u001B[2mhttp\u001B[22m')
30+
expect(routerTest1).to.equal(`${colors.green1}2018-01-01T00:00:00.00+00:00 heroku[router]:${colors.reset} ${colors.dim}works${colors.reset} ${colors.dim}with${colors.reset} ${colors.dim}bare${colors.reset} ${colors.dim}words${colors.reset} ${colors.dim}at=${colors.reset}${colors.dim}info${colors.reset} ${colors.dim}method=${colors.reset}${colors.magenta1}POST${colors.reset} ${colors.dim}path=${colors.reset}${colors.green1}"/record?start=123&end=321"${colors.reset} ${colors.dim}host=${colors.reset}${colors.dim}cli-analytics.heroku.com${colors.reset} ${colors.dim}request_id=${colors.reset}${colors.dim}0fb9c505-5d65-4e63-8fee-fa18da33ee47${colors.reset} ${colors.dim}fwd=${colors.reset}${colors.dim}"50.233.199.252"${colors.reset} ${colors.dim}dyno=${colors.reset}${colors.cyan1}web.1${colors.reset} ${colors.dim}connect=${colors.reset}${colors.green1}1ms${colors.reset} ${colors.dim}service=${colors.reset}${colors.green1}14ms${colors.reset} ${colors.dim}status=${colors.reset}${colors.green1}201${colors.reset} ${colors.dim}bytes=${colors.reset}${colors.dim}255${colors.reset} ${colors.dim}protocol=${colors.reset}${colors.dim}https${colors.reset}`)
31+
expect(routerTest2).to.equal(`${colors.green1}2018-01-01T00:00:00.00+00:00 heroku[router]:${colors.reset} ${colors.dim}at=${colors.reset}${colors.red}error${colors.reset} ${colors.dim}code=${colors.reset}${colors.red}${colors.bold}H12${colors.resetBold}${colors.reset} ${colors.dim}desc=${colors.reset}${colors.dim}"Request${colors.reset} ${colors.dim}timeout"${colors.reset} ${colors.dim}method=${colors.reset}${colors.magenta1}GET${colors.reset} ${colors.dim}path=${colors.reset}${colors.green1}/${colors.reset} ${colors.dim}host=${colors.reset}${colors.dim}myapp.herokuapp.com${colors.reset} ${colors.dim}request_id=${colors.reset}${colors.dim}8601b555-6a83-4c12-8269-97c8e32cdb22${colors.reset} ${colors.dim}fwd=${colors.reset}${colors.dim}"204.204.204.204"${colors.reset} ${colors.dim}dyno=${colors.reset}${colors.cyan1}web.1${colors.reset} ${colors.dim}connect=${colors.reset} ${colors.dim}service=${colors.reset}${colors.red}30000ms${colors.reset} ${colors.dim}status=${colors.reset}${colors.red}503${colors.reset} ${colors.dim}bytes=${colors.reset}${colors.dim}0${colors.reset} ${colors.dim}protocol=${colors.reset}${colors.dim}http${colors.reset}`)
1532
})
1633

1734
it('colorizes run logs', function () {
@@ -21,12 +38,12 @@ describe('colorize', function () {
2138
const runTest4 = colorizeTest('run', 'State changed from starting to complete')
2239
const runTest5 = colorizeTest('run', 'Process exited with status 1')
2340
const runTest6 = colorizeTest('run', 'Process exited with status 0')
24-
expect(runTest1).to.equal('\u001B[33m2018-01-01T00:00:00.00+00:00 heroku[run]:\u001B[39m \u001B[31mStopping all processes with SIGTERM\u001B[39m')
25-
expect(runTest2).to.equal('\u001B[33m2018-01-01T00:00:00.00+00:00 heroku[run]:\u001B[39m Starting process with command \u001B[36m\u001B[1m`test-command`\u001B[22m\u001B[39m\u001B[32m by user test user\u001B[39m')
26-
expect(runTest3).to.equal('\u001B[33m2018-01-01T00:00:00.00+00:00 heroku[run]:\u001B[39m State changed from \u001B[31mdown\u001B[39m to \u001B[92mup\u001B[39m')
27-
expect(runTest4).to.equal('\u001B[33m2018-01-01T00:00:00.00+00:00 heroku[run]:\u001B[39m State changed from \u001B[93mstarting\u001B[39m to \u001B[92mcomplete\u001B[39m')
28-
expect(runTest5).to.equal('\u001B[33m2018-01-01T00:00:00.00+00:00 heroku[run]:\u001B[39m Process exited with status \u001B[31m1\u001B[39m')
29-
expect(runTest6).to.equal('\u001B[33m2018-01-01T00:00:00.00+00:00 heroku[run]:\u001B[39m Process exited with status \u001B[92m0\u001B[39m')
41+
expect(runTest1).to.equal(`${colors.yellow}2018-01-01T00:00:00.00+00:00 heroku[run]:${colors.reset} ${colors.red}Stopping all processes with SIGTERM${colors.reset}`)
42+
expect(runTest2).to.equal(`${colors.yellow}2018-01-01T00:00:00.00+00:00 heroku[run]:${colors.reset} Starting process with command ${colors.bgGray}${colors.white}${colors.bold}\`test-command\`${colors.resetBold}${colors.reset}${colors.resetBg}${colors.green1} by user test user${colors.reset}`)
43+
expect(runTest3).to.equal(`${colors.yellow}2018-01-01T00:00:00.00+00:00 heroku[run]:${colors.reset} State changed from ${colors.red}down${colors.reset} to ${colors.green1}up${colors.reset}`)
44+
expect(runTest4).to.equal(`${colors.yellow}2018-01-01T00:00:00.00+00:00 heroku[run]:${colors.reset} State changed from ${colors.green2}starting${colors.reset} to ${colors.green1}complete${colors.reset}`)
45+
expect(runTest5).to.equal(`${colors.yellow}2018-01-01T00:00:00.00+00:00 heroku[run]:${colors.reset} Process exited with status ${colors.red}1${colors.reset}`)
46+
expect(runTest6).to.equal(`${colors.yellow}2018-01-01T00:00:00.00+00:00 heroku[run]:${colors.reset} Process exited with status ${colors.green1}0${colors.reset}`)
3047
})
3148

3249
it('colorizes web logs', function () {
@@ -40,16 +57,16 @@ describe('colorize', function () {
4057
const webTest8 = colorizeTest('web', 'Process exited with status 0')
4158
const webTest9 = colorizeTest('web', '186.141.134.146 - - [07/May/2018:22:43:54 +0000] "POST /record HTTP/1.1" 201 20 "-" "http-call/3.0.2 node-v8.7.0"')
4259
const webTest10 = colorizeTest('web', '2018/05/07 22:32:24 [cc1a13bb-1427-4085-a632-57095b016c94/7PUOz5O3BG-000001] "POST http://heroku-cli-auth-staging.herokuapp.com/auth HTTP/1.1" from 24.22.53.209 - 201 344B in 403.241µs')
43-
expect(webTest1).to.equal('\u001B[36m2018-01-01T00:00:00.00+00:00 heroku[web]:\u001B[39m \u001B[33mUnidling\u001B[39m')
44-
expect(webTest2).to.equal('\u001B[36m2018-01-01T00:00:00.00+00:00 heroku[web]:\u001B[39m \u001B[33mRestarting\u001B[39m')
45-
expect(webTest3).to.equal('\u001B[36m2018-01-01T00:00:00.00+00:00 heroku[web]:\u001B[39m \u001B[31mStopping all processes with SIGTERM\u001B[39m')
46-
expect(webTest4).to.equal('\u001B[36m2018-01-01T00:00:00.00+00:00 heroku[web]:\u001B[39m Starting process with command \u001B[36m\u001B[1m`test-command`\u001B[22m\u001B[39m\u001B[32m by user test user\u001B[39m')
47-
expect(webTest5).to.equal('\u001B[36m2018-01-01T00:00:00.00+00:00 heroku[web]:\u001B[39m State changed from \u001B[31mdown\u001B[39m to \u001B[92mup\u001B[39m')
48-
expect(webTest6).to.equal('\u001B[36m2018-01-01T00:00:00.00+00:00 heroku[web]:\u001B[39m State changed from \u001B[93mstarting\u001B[39m to \u001B[92mcomplete\u001B[39m')
49-
expect(webTest7).to.equal('\u001B[36m2018-01-01T00:00:00.00+00:00 heroku[web]:\u001B[39m Process exited with status \u001B[31m1\u001B[39m')
50-
expect(webTest8).to.equal('\u001B[36m2018-01-01T00:00:00.00+00:00 heroku[web]:\u001B[39m Process exited with status \u001B[92m0\u001B[39m')
51-
expect(webTest9).to.equal('\u001B[36m2018-01-01T00:00:00.00+00:00 heroku[web]:\u001B[39m \u001B[2m186.141.134.146 - - [07/May/2018:22:43:54 +0000] "\u001B[22m\u001B[1m\u001B[35mPOST\u001B[39m\u001B[22m\u001B[2m \u001B[22m\u001B[32m/record\u001B[39m\u001B[2m HTTP/1.1" \u001B[22m\u001B[32m201\u001B[39m\u001B[2m 20 "-" "http-call/3.0.2 node-v8.7.0"\u001B[22m')
52-
expect(webTest10).to.equal('\u001B[36m2018-01-01T00:00:00.00+00:00 heroku[web]:\u001B[39m 2018/05/07 22:32:24 [cc1a13bb-1427-4085-a632-57095b016c94/7PUOz5O3BG-000001] "\u001B[1m\u001B[35mPOST\u001B[39m\u001B[22m\u001B[32m http://heroku-cli-auth-staging.herokuapp.com/auth \u001B[39mHTTP/1.1" from 24.22.53.209 - 201 344B in 403.241µs')
60+
expect(webTest1).to.equal(`${colors.cyan1}2018-01-01T00:00:00.00+00:00 heroku[web]:${colors.reset} ${colors.yellow}Unidling${colors.reset}`)
61+
expect(webTest2).to.equal(`${colors.cyan1}2018-01-01T00:00:00.00+00:00 heroku[web]:${colors.reset} ${colors.yellow}Restarting${colors.reset}`)
62+
expect(webTest3).to.equal(`${colors.cyan1}2018-01-01T00:00:00.00+00:00 heroku[web]:${colors.reset} ${colors.red}Stopping all processes with SIGTERM${colors.reset}`)
63+
expect(webTest4).to.equal(`${colors.cyan1}2018-01-01T00:00:00.00+00:00 heroku[web]:${colors.reset} Starting process with command ${colors.bgGray}${colors.white}${colors.bold}\`test-command\`${colors.resetBold}${colors.reset}${colors.resetBg}${colors.green1} by user test user${colors.reset}`)
64+
expect(webTest5).to.equal(`${colors.cyan1}2018-01-01T00:00:00.00+00:00 heroku[web]:${colors.reset} State changed from ${colors.red}down${colors.reset} to ${colors.green1}up${colors.reset}`)
65+
expect(webTest6).to.equal(`${colors.cyan1}2018-01-01T00:00:00.00+00:00 heroku[web]:${colors.reset} State changed from ${colors.green2}starting${colors.reset} to ${colors.green1}complete${colors.reset}`)
66+
expect(webTest7).to.equal(`${colors.cyan1}2018-01-01T00:00:00.00+00:00 heroku[web]:${colors.reset} Process exited with status ${colors.red}1${colors.reset}`)
67+
expect(webTest8).to.equal(`${colors.cyan1}2018-01-01T00:00:00.00+00:00 heroku[web]:${colors.reset} Process exited with status ${colors.green1}0${colors.reset}`)
68+
expect(webTest9).to.equal(`${colors.cyan1}2018-01-01T00:00:00.00+00:00 heroku[web]:${colors.reset} ${colors.dim}186.141.134.146 - - [07/May/2018:22:43:54 +0000] "${colors.reset}${colors.magenta1}POST${colors.reset}${colors.dim} ${colors.reset}${colors.green1}/record${colors.reset}${colors.dim} HTTP/1.1" ${colors.reset}${colors.green1}201${colors.reset}${colors.dim} 20 "-" "http-call/3.0.2 node-v8.7.0"${colors.reset}`)
69+
expect(webTest10).to.equal(`${colors.cyan1}2018-01-01T00:00:00.00+00:00 heroku[web]:${colors.reset} 2018/05/07 22:32:24 [cc1a13bb-1427-4085-a632-57095b016c94/7PUOz5O3BG-000001] "${colors.magenta1}POST${colors.reset}${colors.green1} http://heroku-cli-auth-staging.herokuapp.com/auth ${colors.reset}HTTP/1.1" from 24.22.53.209 - 201 344B in 403.241µs`)
5370
})
5471

5572
it('colorizes api logs', function () {
@@ -59,32 +76,30 @@ describe('colorize', function () {
5976
const apiTest4 = colorizeTest('api', 'Deploy testApp by user test-user')
6077
const apiTest5 = colorizeTest('api', 'Release v1 created by user test-user')
6178
const apiTest6 = colorizeTest('api', 'Starting process with command `test-command` by user test-user')
62-
expect(apiTest1).to.equal('\u001B[1m\u001B[32m2018-01-01T00:00:00.00+00:00 heroku[api]:\u001B[39m\u001B[22m \u001B[92mBuild succeeded\u001B[39m')
63-
expect(apiTest2).to.equal('\u001B[1m\u001B[32m2018-01-01T00:00:00.00+00:00 heroku[api]:\u001B[39m\u001B[22m \u001B[31mBuild failed\u001B[39m')
64-
expect(apiTest3).to.equal('\u001B[1m\u001B[32m2018-01-01T00:00:00.00+00:00 heroku[api]:\u001B[39m\u001B[22m Build started by user \u001B[32mtest-user\u001B[39m')
65-
expect(apiTest4).to.equal('\u001B[1m\u001B[32m2018-01-01T00:00:00.00+00:00 heroku[api]:\u001B[39m\u001B[22m Deploy \u001B[36mtestApp\u001B[39m by user \u001B[32mtest-user\u001B[39m')
66-
expect(apiTest5).to.equal('\u001B[1m\u001B[32m2018-01-01T00:00:00.00+00:00 heroku[api]:\u001B[39m\u001B[22m Release \u001B[35mv1\u001B[39m created by user \u001B[32mtest-user\u001B[39m')
67-
expect(apiTest6).to.equal('\u001B[1m\u001B[32m2018-01-01T00:00:00.00+00:00 heroku[api]:\u001B[39m\u001B[22m Starting process with command \u001B[36m\u001B[1m`test-command`\u001B[22m\u001B[39m\u001B[32m by user test-user\u001B[39m')
79+
expect(apiTest1).to.equal(`${colors.green2}2018-01-01T00:00:00.00+00:00 heroku[api]:${colors.reset} ${colors.green1}Build succeeded${colors.reset}`)
80+
expect(apiTest2).to.equal(`${colors.green2}2018-01-01T00:00:00.00+00:00 heroku[api]:${colors.reset} ${colors.red}Build failed${colors.reset}`)
81+
expect(apiTest3).to.equal(`${colors.green2}2018-01-01T00:00:00.00+00:00 heroku[api]:${colors.reset} Build started by user ${colors.green1}test-user${colors.reset}`)
82+
expect(apiTest4).to.equal(`${colors.green2}2018-01-01T00:00:00.00+00:00 heroku[api]:${colors.reset} Deploy ${colors.cyan1}testApp${colors.reset} by user ${colors.green1}test-user${colors.reset}`)
83+
expect(apiTest5).to.equal(`${colors.green2}2018-01-01T00:00:00.00+00:00 heroku[api]:${colors.reset} Release ${colors.magenta1}v1${colors.reset} created by user ${colors.green1}test-user${colors.reset}`)
84+
expect(apiTest6).to.equal(`${colors.green2}2018-01-01T00:00:00.00+00:00 heroku[api]:${colors.reset} Starting process with command ${colors.bgGray}${colors.white}${colors.bold}\`test-command\`${colors.resetBold}${colors.reset}${colors.resetBg}${colors.green1} by user test-user${colors.reset}`)
6885
})
6986

7087
it('colorizes redis logs', function () {
7188
const redisTest = colorizeTest('heroku-redis', 'source=testsource sample#333')
72-
expect(redisTest).to.equal('\u001B[1m\u001B[36m2018-01-01T00:00:00.00+00:00 heroku[heroku-redis]:\u001B[39m\u001B[22m \u001B[2msource=testsource sample#333\u001B[22m')
89+
expect(redisTest).to.equal(`${colors.magenta2}2018-01-01T00:00:00.00+00:00 heroku[heroku-redis]:${colors.reset} ${colors.dim}source=testsource sample#333${colors.reset}`)
7390
})
7491

7592
it('colorizes heroku-postgres logs', function () {
7693
const pgTest1 = colorizeTest('heroku-postgres', '[DATABASE] test-database CREATE TABLE test-table')
7794
const pgTest2 = colorizeTest('heroku-postgres', 'source=testsource sample#333')
78-
expect(pgTest1).to.contain('heroku[heroku-postgres]:\u001B[39m \u001B[2m[DATABASE] test-database \u001B[22m\u001B[35mCREATE TABLE\u001B[39m\u001B[36m test-table\u001B[39m')
79-
expect(pgTest2).to.contain('heroku[heroku-postgres]:\u001B[39m \u001B[2msource=testsource sample#333\u001B[22m')
95+
expect(pgTest1).to.contain(`heroku[heroku-postgres]:${colors.reset} ${colors.dim}[DATABASE] test-database ${colors.reset}${colors.magenta1}CREATE TABLE${colors.reset}${colors.cyan1} test-table${colors.reset}`)
96+
expect(pgTest2).to.contain(`heroku[heroku-postgres]:${colors.reset} ${colors.dim}source=testsource sample#333${colors.reset}`)
8097
})
8198

8299
it('colorizes postgres logs', function () {
83100
const pgTest1 = colorizeTest('postgres', '[DATABASE] test-database CREATE TABLE test-table')
84101
const pgTest2 = colorizeTest('postgres', 'source=testsource sample#333')
85-
expect(pgTest1).to.equal('\u001B[35m2018-01-01T00:00:00.00+00:00 heroku[postgres]:\u001B[39m \u001B[2m[DATABASE] test-database \u001B[22m\u001B[35mCREATE TABLE\u001B[39m\u001B[36m test-table\u001B[39m')
86-
expect(pgTest2).to.equal('\u001B[35m2018-01-01T00:00:00.00+00:00 heroku[postgres]:\u001B[39m \u001B[2msource=testsource sample#333\u001B[22m')
102+
expect(pgTest1).to.equal(`${colors.magenta1}2018-01-01T00:00:00.00+00:00 heroku[postgres]:${colors.reset} ${colors.dim}[DATABASE] test-database ${colors.reset}${colors.magenta1}CREATE TABLE${colors.reset}${colors.cyan1} test-table${colors.reset}`)
103+
expect(pgTest2).to.equal(`${colors.magenta1}2018-01-01T00:00:00.00+00:00 heroku[postgres]:${colors.reset} ${colors.dim}source=testsource sample#333${colors.reset}`)
87104
})
88105
})
89-
90-
*/

0 commit comments

Comments
 (0)