[READ-ONLY] Mirror of https://github.com/bombshell-dev/clack. Effortlessly build beautiful command-line apps bomb.sh/docs/clack/basics/getting-started/
cli command-line command-line-app node prompt prompts
5

Configure Feed

Select the types of activity you want to include in your feed.

chore: enable colours when running pnpm (#267)

authored by

James Garbutt and committed by
GitHub
(Apr 4, 2025, 2:07 PM +0100) 2ad8000e 17342d20

+202 -84
+1 -1
package.json
··· 10 10 "format": "biome check --write", 11 11 "lint": "biome lint --write --unsafe", 12 12 "type-check": "biome lint && tsc", 13 - "test": "pnpm -r run test", 13 + "test": "pnpm --color -r run test", 14 14 "ci:version": "changeset version && pnpm install --no-frozen-lockfile", 15 15 "ci:publish": "changeset publish" 16 16 },
+113 -8
packages/prompts/src/__snapshots__/index.test.ts.snap
··· 1 1 // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 2 3 - exports[`spinner > message > sets message for next frame 1`] = ` 3 + exports[`isCI = false > spinner > message > sets message for next frame 1`] = ` 4 4 [ 5 5 "[?25l", 6 6 "│ ··· 12 12 ] 13 13 `; 14 14 15 - exports[`spinner > start > renders frames at interval 1`] = ` 15 + exports[`isCI = false > spinner > start > renders frames at interval 1`] = ` 16 16 [ 17 17 "[?25l", 18 18 "│ ··· 30 30 ] 31 31 `; 32 32 33 - exports[`spinner > start > renders message 1`] = ` 33 + exports[`isCI = false > spinner > start > renders message 1`] = ` 34 34 [ 35 35 "[?25l", 36 36 "│ ··· 39 39 ] 40 40 `; 41 41 42 - exports[`spinner > start > renders timer when indicator is "timer" 1`] = ` 42 + exports[`isCI = false > spinner > start > renders timer when indicator is "timer" 1`] = ` 43 43 [ 44 44 "[?25l", 45 45 "│ ··· 48 48 ] 49 49 `; 50 50 51 - exports[`spinner > stop > renders cancel symbol if code = 1 1`] = ` 51 + exports[`isCI = false > spinner > stop > renders cancel symbol if code = 1 1`] = ` 52 52 [ 53 53 "[?25l", 54 54 "│ ··· 62 62 ] 63 63 `; 64 64 65 - exports[`spinner > stop > renders error symbol if code > 1 1`] = ` 65 + exports[`isCI = false > spinner > stop > renders error symbol if code > 1 1`] = ` 66 66 [ 67 67 "[?25l", 68 68 "│ ··· 76 76 ] 77 77 `; 78 78 79 - exports[`spinner > stop > renders message 1`] = ` 79 + exports[`isCI = false > spinner > stop > renders message 1`] = ` 80 80 [ 81 81 "[?25l", 82 82 "│ ··· 90 90 ] 91 91 `; 92 92 93 - exports[`spinner > stop > renders submit symbol and stops spinner 1`] = ` 93 + exports[`isCI = false > spinner > stop > renders submit symbol and stops spinner 1`] = ` 94 94 [ 95 95 "[?25l", 96 96 "│ ··· 103 103 "[?25h", 104 104 ] 105 105 `; 106 + 107 + exports[`isCI = true > spinner > message > sets message for next frame 1`] = ` 108 + [ 109 + "[?25l", 110 + "│ 111 + ", 112 + "◒ ...", 113 + " 114 + ", 115 + "", 116 + "", 117 + "◐ foo...", 118 + ] 119 + `; 120 + 121 + exports[`isCI = true > spinner > start > renders frames at interval 1`] = ` 122 + [ 123 + "[?25l", 124 + "│ 125 + ", 126 + "◒ ...", 127 + ] 128 + `; 129 + 130 + exports[`isCI = true > spinner > start > renders message 1`] = ` 131 + [ 132 + "[?25l", 133 + "│ 134 + ", 135 + "◒ foo...", 136 + ] 137 + `; 138 + 139 + exports[`isCI = true > spinner > start > renders timer when indicator is "timer" 1`] = ` 140 + [ 141 + "[?25l", 142 + "│ 143 + ", 144 + "◒ ...", 145 + ] 146 + `; 147 + 148 + exports[`isCI = true > spinner > stop > renders cancel symbol if code = 1 1`] = ` 149 + [ 150 + "[?25l", 151 + "│ 152 + ", 153 + "◒ ...", 154 + " 155 + ", 156 + "", 157 + "", 158 + "■ 159 + ", 160 + "[?25h", 161 + ] 162 + `; 163 + 164 + exports[`isCI = true > spinner > stop > renders error symbol if code > 1 1`] = ` 165 + [ 166 + "[?25l", 167 + "│ 168 + ", 169 + "◒ ...", 170 + " 171 + ", 172 + "", 173 + "", 174 + "▲ 175 + ", 176 + "[?25h", 177 + ] 178 + `; 179 + 180 + exports[`isCI = true > spinner > stop > renders message 1`] = ` 181 + [ 182 + "[?25l", 183 + "│ 184 + ", 185 + "◒ ...", 186 + " 187 + ", 188 + "", 189 + "", 190 + "◇ foo 191 + ", 192 + "[?25h", 193 + ] 194 + `; 195 + 196 + exports[`isCI = true > spinner > stop > renders submit symbol and stops spinner 1`] = ` 197 + [ 198 + "[?25l", 199 + "│ 200 + ", 201 + "◒ ...", 202 + " 203 + ", 204 + "", 205 + "", 206 + "◇ 207 + ", 208 + "[?25h", 209 + ] 210 + `;
+88 -75
packages/prompts/src/index.test.ts
··· 1 1 import { Writable } from 'node:stream'; 2 - import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'; 2 + import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, test, vi } from 'vitest'; 3 3 import * as prompts from './index.js'; 4 4 5 5 // TODO (43081j): move this into a util? ··· 16 16 } 17 17 } 18 18 19 - describe('spinner', () => { 20 - let output: MockWritable; 19 + describe.each(['true', 'false'])('isCI = %s', (isCI) => { 20 + let originalCI: string | undefined; 21 21 22 - beforeEach(() => { 23 - vi.useFakeTimers(); 24 - output = new MockWritable(); 22 + beforeAll(() => { 23 + originalCI = process.env.CI; 24 + process.env.CI = isCI; 25 25 }); 26 26 27 - afterEach(() => { 28 - vi.restoreAllMocks(); 29 - vi.useRealTimers(); 27 + afterAll(() => { 28 + process.env.CI = originalCI; 30 29 }); 31 30 32 - test('returns spinner API', () => { 33 - const api = prompts.spinner({ output }); 31 + describe('spinner', () => { 32 + let output: MockWritable; 34 33 35 - expect(api.stop).toBeTypeOf('function'); 36 - expect(api.start).toBeTypeOf('function'); 37 - expect(api.message).toBeTypeOf('function'); 38 - }); 39 - 40 - describe('start', () => { 41 - test('renders frames at interval', () => { 42 - const result = prompts.spinner({ output }); 34 + beforeEach(() => { 35 + vi.useFakeTimers(); 36 + output = new MockWritable(); 37 + }); 43 38 44 - result.start(); 39 + afterEach(() => { 40 + vi.restoreAllMocks(); 41 + vi.useRealTimers(); 42 + }); 45 43 46 - // there are 4 frames 47 - for (let i = 0; i < 4; i++) { 48 - vi.advanceTimersByTime(80); 49 - } 44 + test('returns spinner API', () => { 45 + const api = prompts.spinner({ output }); 50 46 51 - expect(output.buffer).toMatchSnapshot(); 47 + expect(api.stop).toBeTypeOf('function'); 48 + expect(api.start).toBeTypeOf('function'); 49 + expect(api.message).toBeTypeOf('function'); 52 50 }); 53 51 54 - test('renders message', () => { 55 - const result = prompts.spinner({ output }); 52 + describe('start', () => { 53 + test('renders frames at interval', () => { 54 + const result = prompts.spinner({ output }); 55 + 56 + result.start(); 57 + 58 + // there are 4 frames 59 + for (let i = 0; i < 4; i++) { 60 + vi.advanceTimersByTime(80); 61 + } 62 + 63 + expect(output.buffer).toMatchSnapshot(); 64 + }); 65 + 66 + test('renders message', () => { 67 + const result = prompts.spinner({ output }); 56 68 57 - result.start('foo'); 69 + result.start('foo'); 58 70 59 - vi.advanceTimersByTime(80); 71 + vi.advanceTimersByTime(80); 60 72 61 - expect(output.buffer).toMatchSnapshot(); 62 - }); 73 + expect(output.buffer).toMatchSnapshot(); 74 + }); 63 75 64 - test('renders timer when indicator is "timer"', () => { 65 - const result = prompts.spinner({ output, indicator: 'timer' }); 76 + test('renders timer when indicator is "timer"', () => { 77 + const result = prompts.spinner({ output, indicator: 'timer' }); 66 78 67 - result.start(); 79 + result.start(); 68 80 69 - vi.advanceTimersByTime(80); 81 + vi.advanceTimersByTime(80); 70 82 71 - expect(output.buffer).toMatchSnapshot(); 83 + expect(output.buffer).toMatchSnapshot(); 84 + }); 72 85 }); 73 - }); 74 86 75 - describe('stop', () => { 76 - test('renders submit symbol and stops spinner', () => { 77 - const result = prompts.spinner({ output }); 87 + describe('stop', () => { 88 + test('renders submit symbol and stops spinner', () => { 89 + const result = prompts.spinner({ output }); 78 90 79 - result.start(); 91 + result.start(); 80 92 81 - vi.advanceTimersByTime(80); 93 + vi.advanceTimersByTime(80); 82 94 83 - result.stop(); 95 + result.stop(); 84 96 85 - vi.advanceTimersByTime(80); 97 + vi.advanceTimersByTime(80); 86 98 87 - expect(output.buffer).toMatchSnapshot(); 88 - }); 99 + expect(output.buffer).toMatchSnapshot(); 100 + }); 89 101 90 - test('renders cancel symbol if code = 1', () => { 91 - const result = prompts.spinner({ output }); 102 + test('renders cancel symbol if code = 1', () => { 103 + const result = prompts.spinner({ output }); 92 104 93 - result.start(); 105 + result.start(); 94 106 95 - vi.advanceTimersByTime(80); 107 + vi.advanceTimersByTime(80); 96 108 97 - result.stop('', 1); 109 + result.stop('', 1); 98 110 99 - expect(output.buffer).toMatchSnapshot(); 100 - }); 111 + expect(output.buffer).toMatchSnapshot(); 112 + }); 101 113 102 - test('renders error symbol if code > 1', () => { 103 - const result = prompts.spinner({ output }); 114 + test('renders error symbol if code > 1', () => { 115 + const result = prompts.spinner({ output }); 104 116 105 - result.start(); 117 + result.start(); 106 118 107 - vi.advanceTimersByTime(80); 119 + vi.advanceTimersByTime(80); 108 120 109 - result.stop('', 2); 121 + result.stop('', 2); 110 122 111 - expect(output.buffer).toMatchSnapshot(); 112 - }); 123 + expect(output.buffer).toMatchSnapshot(); 124 + }); 113 125 114 - test('renders message', () => { 115 - const result = prompts.spinner({ output }); 126 + test('renders message', () => { 127 + const result = prompts.spinner({ output }); 116 128 117 - result.start(); 129 + result.start(); 118 130 119 - vi.advanceTimersByTime(80); 131 + vi.advanceTimersByTime(80); 120 132 121 - result.stop('foo'); 133 + result.stop('foo'); 122 134 123 - expect(output.buffer).toMatchSnapshot(); 135 + expect(output.buffer).toMatchSnapshot(); 136 + }); 124 137 }); 125 - }); 126 138 127 - describe('message', () => { 128 - test('sets message for next frame', () => { 129 - const result = prompts.spinner({ output }); 139 + describe('message', () => { 140 + test('sets message for next frame', () => { 141 + const result = prompts.spinner({ output }); 130 142 131 - result.start(); 143 + result.start(); 132 144 133 - vi.advanceTimersByTime(80); 145 + vi.advanceTimersByTime(80); 134 146 135 - result.message('foo'); 147 + result.message('foo'); 136 148 137 - vi.advanceTimersByTime(80); 149 + vi.advanceTimersByTime(80); 138 150 139 - expect(output.buffer).toMatchSnapshot(); 151 + expect(output.buffer).toMatchSnapshot(); 152 + }); 140 153 }); 141 154 }); 142 155 });