-
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
CLI: Improve support for upgrading Storybook in monorepos #31557
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
240 commits
Select commit
Hold shift + click to select a range
8536401
add prompts abstraction
yannbf ad924e8
experiment with clack
yannbf a718ece
Encapsulate boxen usage in cli-storybook
yannbf 745682d
cleanup
yannbf 16531c5
cleanup
yannbf b7df284
fix types
yannbf 7991203
use onCancel as a base option
yannbf 50e1bd2
fix tests
yannbf 6cee77a
try to fix test on windows
yannbf 3a55010
fix
yannbf 721aba0
Merge pull request #31521 from storybookjs/yann/prompts-abstraction
yannbf bd45265
detect multiple config dirs for the upgrade command
yannbf 336c11f
updates
yannbf b9fe8b5
fix types
yannbf 01c350d
remove unused code
yannbf 6356cf3
further updates
yannbf c13b712
Core: Improve mono repo handling for JsPackageManager class and helpers
valentinpalkovic 566b526
Fix Angular sandbox
valentinpalkovic 4737b92
Remove unused import
valentinpalkovic 6436065
Fix types
valentinpalkovic 5595040
Smaller fixes
valentinpalkovic eac2647
Install at the end of automigrations
valentinpalkovic 69b3764
Fix tests
valentinpalkovic ef8f4f2
Core: Use `projectRoot` consequently and limit `find-up` actions to t…
valentinpalkovic b3e5ca2
fix tests
yannbf 852679e
Revert projectRoot usage to getProjectRoot
valentinpalkovic 7edd821
Fix initialization in empty directory + improvements in init
valentinpalkovic 034dbf6
Fix import and reference issues
valentinpalkovic 4092bac
Fix tests
valentinpalkovic 480594b
fix tests
yannbf 7becd44
fix test init flow
yannbf 1239c0f
Fix initialization in empty directory
valentinpalkovic 4aa4cf1
Merge branch 'valentin/improve-monorepo-support-for-js-package-manage…
yannbf be484bf
Merge pull request #31553 from storybookjs/valentin/improve-monorepo-…
yannbf 3021866
wip
yannbf 59d6fb8
detect upgrade data per config dir
yannbf 9059079
Merge remote-tracking branch 'origin/valentin/monorepo-enhancements' …
valentinpalkovic e29270b
Move helpers into util files
valentinpalkovic a4fb051
Move helpers into util files
valentinpalkovic 4e3c111
Cleanup
valentinpalkovic 7fe300f
Enhance compatibility checks by integrating JsPackageManager into war…
valentinpalkovic c0e1e66
Merge remote-tracking branch 'origin/next' into valentin/monorepo-enh…
valentinpalkovic 70c7095
Merge remote-tracking branch 'origin/valentin/monorepo-enhancements' …
valentinpalkovic bb87272
Improve options interface for removing addons
valentinpalkovic 142742a
Refactor upgrade function to use CollectProjectsSuccessResult type an…
valentinpalkovic 4f266b2
add log methods
yannbf 8b4b394
Centralize autoblockers
valentinpalkovic 9d9dedf
Add error handling in upgrades
valentinpalkovic c75e93e
Fix type errors
valentinpalkovic 8073cf7
Fix unit tests
valentinpalkovic 37e1091
Fix init
valentinpalkovic 4ce4625
Fix init
valentinpalkovic 337c391
Merge pull request #31534 from storybookjs/yann/detect-multiple-confi…
yannbf dc5cde1
cleanup
yannbf 88b9aac
CLI: Improve package manager execution and CLI logging
yannbf 433e40f
use clack in more places
yannbf e0e28eb
Remove package.json as input for autoblockers
valentinpalkovic ebd87d1
install correct version of addon docs in automigrations
yannbf 3c1c790
silence automigrations and skip doctor checks
yannbf e19ac2d
Refactor automigrations to scope their actions to a specific project
valentinpalkovic 308ce03
fix test
yannbf 18cab60
Merge branch 'valentin/monorepo-enhancements' into yann/silence-posti…
yannbf 17d7065
fix tests
yannbf 24465b6
Merge branch 'next' into valentin/monorepo-enhancements
yannbf 22e9c8d
Fix tests
valentinpalkovic a0bb356
Fix tests
valentinpalkovic df54379
fix tests
yannbf aecf389
Merge pull request #31589 from storybookjs/yann/silence-postinstall-s…
yannbf fe8e0a3
remove testing limitation
yannbf bec3d72
Merge branch 'valentin/monorepo-enhancements' into yann/improve-logger
yannbf 758a2da
refactor
yannbf 60b23ae
Merge remote-tracking branch 'origin/valentin/monorepo-enhancements' …
valentinpalkovic 6639cb5
Merge remote-tracking branch 'origin/next' into valentin/monorepo-enh…
valentinpalkovic ed23d23
Merge remote-tracking branch 'origin/valentin/monorepo-enhancements' …
valentinpalkovic 1d5a99a
Centralize automigration check function run
valentinpalkovic 0a4f572
Refactor autoblocker handling by centralizing logic in processAutoblo…
valentinpalkovic 0456eec
add debug messages
valentinpalkovic 26e13ec
add back optional prompts implementation
yannbf fc8ba49
Refactor story path handling by introducing getEvaluatedStoryPaths fu…
yannbf 16ea496
Merge branch 'valentin/automigration-adjustments-for-monorepo-support…
yannbf 8f9956a
Merge pull request #31588 from storybookjs/valentin/automigration-adj…
valentinpalkovic b48bd7b
improvements
yannbf cc9f393
install deps before running storybook doctor
yannbf c5da213
Merge branch 'valentin/monorepo-enhancements' into yann/improve-logger
yannbf 5f2ee1d
Centralize doctor logic
valentinpalkovic 170f3bf
Merge branch 'valentin/monorepo-enhancements' into yann/improve-logger
yannbf 424878f
improvements
yannbf 98c234a
introduce runInternalCommand function to jspackage manager
yannbf 2c92b9b
make removeAddon fault tolerant
yannbf 4372d63
filter out addons with invalid versions in the upgrade checks
yannbf fd6009e
optimize automigrate command (when run via sb automigrate)
yannbf 69bd171
move fix
yannbf 243f0aa
improve logging
yannbf d9c41cd
fix
yannbf b73a6e0
fix tests
yannbf d1a7ca9
improve logging and storybook doctor
yannbf 9062515
add multi-upgrade telemetry
yannbf e460564
fix build
yannbf 9e7dd0b
fix
yannbf f16af7c
remove circular dependency in prep script
yannbf 5bed749
fix check
yannbf af5d58c
fix tests
yannbf a69535d
fix tests?
yannbf 2f91023
Merge pull request #31583 from storybookjs/yann/improve-logger
yannbf 3da5052
Revamp prompting and logging
yannbf 006c107
fix tests
yannbf 9111cd3
improve executeTasks
yannbf 7a9ce31
Limit usage area of findup
valentinpalkovic b18b0cb
Don't ignore errors when installing dependencies
valentinpalkovic 90be96a
Enhance logging capabilities with clack
valentinpalkovic 7101d9d
Improve automigrations to support monorepos
valentinpalkovic a1d90bd
Improve prompting
valentinpalkovic 494bc66
fix tests
yannbf 864e040
Add test suite
valentinpalkovic aecae78
fix tests
yannbf f5c2ce8
Merge pull request #31641 from storybookjs/yann/logger-improvements
yannbf d4d13f2
Improve performance of JsPackageManagerFactory
valentinpalkovic 2ebadd1
Merge branch 'next' into valentin/monorepo-enhancements
yannbf 647f970
remove duplicated flag
yannbf c895f14
finalize telemetry changes
yannbf 66805b6
streamline logging in node-logger
yannbf 1e3ee7e
fix
yannbf da4d566
Enhance project collection by limiting concurrency and improving task…
valentinpalkovic d5aea37
fix
yannbf ab53807
Merge remote-tracking branch 'origin/valentin/monorepo-enhancements' …
valentinpalkovic 0dceba4
Fix doctor after rebase
valentinpalkovic 34091b6
remove .only
yannbf bbf71e3
fix types
yannbf 6ace76c
fix types
yannbf 959d55b
Merge branch 'valentin/monorepo-enhancements' into yann/use-logger-ev…
yannbf 3d617f0
Truncate links and improve automigration selection logger
valentinpalkovic b4098ac
Merge remote-tracking branch 'origin/valentin/monorepo-enhancements' …
valentinpalkovic b4c7a96
augment tasklog and spinner to track logs
yannbf 1478b6d
Further improvements
valentinpalkovic 4257a54
Re-add tests
valentinpalkovic cb4d179
Further prompt improvements
valentinpalkovic 58afbc6
fix
yannbf 8c4786d
Update code/lib/cli-storybook/src/doctor/index.ts
yannbf 2ee2478
fix eslint plugin configuration messages
yannbf c509d9a
Add caching to JsPackageManagerFactory
valentinpalkovic 7d99086
respect yes flag to multi-project upgrade
yannbf a624504
use loglevel instead of log-level
yannbf 995b8f3
Merge branch 'valentin/monorepo-enhancements' into yann/use-logger-ev…
valentinpalkovic 0cb9ff4
Fix upgradeStorybookDependencies to apply changes to the right packag…
valentinpalkovic 9640ccc
Refactor JsPackageManager to improve dependency removal logic and enh…
valentinpalkovic cd98778
Improve logging experience for autoblockers and additional optimizations
valentinpalkovic 544f249
Rename id of addon-a11y-addon-test automigration
valentinpalkovic 128c6bd
Update automigration command for addon-a11y-addon-test and enhance pa…
valentinpalkovic 8a5431b
Merge remote-tracking branch 'origin/valentin/monorepo-enhancements' …
valentinpalkovic aa1d345
fix
yannbf 2d3f3ca
Merge branch 'yann/use-logger-everywhere' of github.com:storybookjs/s…
yannbf 6edb7a3
fix lint
yannbf 3d31dd0
fixes
yannbf cc78198
fixes
yannbf cb665e2
Merge pull request #31653 from storybookjs/yann/use-logger-everywhere
yannbf 7eb0c2a
Use glob instead of globby
valentinpalkovic ad3bfd5
Merge remote-tracking branch 'origin/valentin/monorepo-enhancements' …
valentinpalkovic a0bb0b5
unify loglevel on other cli commands too
yannbf 9a61700
Fix tests
valentinpalkovic f4994f5
Fix tests
valentinpalkovic 4d6db26
Fix tests
valentinpalkovic 1bf6358
Merge pull request #31642 from storybookjs/valentin/improvements
valentinpalkovic 043366b
Support cjs main.js in wrap-require automigration
valentinpalkovic ff4793b
make sure log files are still written when user cancels step
yannbf 52f3162
Use standardized wrapAnsi options
valentinpalkovic 4797ca9
Merge branch 'next' into valentin/monorepo-enhancements
yannbf d842a94
fix tests on windows
yannbf eb20aa0
fix loglevel and other things
yannbf 996d728
Remove version ranges from automigrations
valentinpalkovic 9b8dda7
Smaller fix
valentinpalkovic db963c6
Limit renaming of rnstorybook-config automigration to selected project
valentinpalkovic e8db0f3
Add support for terminal hyperlinks and improve text wrapping logic
valentinpalkovic 81504ca
Refactor upgradeStorybookDependencies to avoid race condition
valentinpalkovic 12649a8
Reduce colorization of output
valentinpalkovic 460c6ef
Refactor import handling in automigration fixes to use config directory
valentinpalkovic d8065b5
Fix tests
valentinpalkovic 156d3b8
fixes
yannbf 07a0118
Logging improvements
valentinpalkovic f5d38c4
Performance improvements
valentinpalkovic dc6341d
Removed colors
valentinpalkovic a8faca8
Refactor JsPackageManager methods to static and improve command execu…
valentinpalkovic 0a661d4
Add more specific logs
valentinpalkovic a6b3edf
Fix conditional check
valentinpalkovic 7de935e
Refactor addDependencies method to support dependency types and updat…
valentinpalkovic 7fc1842
Improve messaging
valentinpalkovic 7cd979e
improve automigration checks error handling
yannbf 2d37bea
Enhance automigration reporting and streamline success/failure detection
valentinpalkovic 2557104
improvements and fixes
yannbf 0b352d1
Fix telemetry
valentinpalkovic ff10eaf
fix more issues
yannbf 58b1121
Fix multi-project tests
valentinpalkovic 618c4cd
Fix JsPackageManager tests
valentinpalkovic 3efcbef
fixes
yannbf a10ef95
fix sandboxes
yannbf 4dcb63e
Merge branch 'next' into valentin/monorepo-enhancements
yannbf 882b84b
fix automigration count
yannbf c3194b8
Fix JsPackageManager tests
valentinpalkovic 6b8b7cf
Remove deduping during upgrade
valentinpalkovic 609c51f
use logger.debug instead of warn
valentinpalkovic b801b3c
Update JsPackageManager to cache null for failed version retrieval an…
valentinpalkovic 2069a95
Redirect messages to current tasklog
valentinpalkovic ea7487d
Improve logging
valentinpalkovic 95e80f4
Run wrap-require auto migration to the end because it tends to influe…
valentinpalkovic 1694432
Refactor logging in various modules to enhance clarity and consistenc…
valentinpalkovic 186a3a9
Merge remote-tracking branch 'origin/next' into valentin/monorepo-enh…
valentinpalkovic c02c7ad
Improve blocker logging
valentinpalkovic 1fc0b2b
Improve logging of upgrade
valentinpalkovic bf99e97
check for addon docs in package.json and not installations
yannbf a19ae9c
show automigration links at the end of upgrade
yannbf a8652b1
do not exit with process on blockers
yannbf 656b7a3
more updates
yannbf ebb4eeb
small flake fix
yannbf 1b1be45
Merge pull request #31717 from storybookjs/yann/more-fixes
yannbf 7a7067f
Refactor logging in processProject function to remove timing logs for…
valentinpalkovic db2c2f3
Improve autoblocker logging
valentinpalkovic bfd7f47
Refactor and enhance logging in upgrade process, removing deprecated …
valentinpalkovic e318cfa
Update compatibility warning message format in getIncompatiblePackage…
valentinpalkovic b888361
Update diagnostic message format in getDoctorDiagnostics for improved…
valentinpalkovic 0ef885d
Refactor automigration links logging in upgrade process for improved …
valentinpalkovic d80423e
Rename cli-color property
valentinpalkovic dfff64d
Add hyperlinks to automigrations
valentinpalkovic dadba8e
fix flake
yannbf fffaddd
fix tests
yannbf 4516861
add dedupe step
yannbf 931cc54
debug flake
yannbf 130ddb9
simplify and fix version range specifier for add command
valentinpalkovic f8ae18d
Remove performance metrics
valentinpalkovic 7d8b72d
fix tests
yannbf 039331f
augment logs
yannbf b1eb45f
Merge branch 'valentin/monorepo-enhancements' of github.com:storybook…
yannbf 435676b
more debugging
yannbf 11e8f9a
Merge remote-tracking branch 'origin/next' into valentin/monorepo-enh…
valentinpalkovic 0664aea
Fix smaller issues
valentinpalkovic 7e132cb
skip savestory tests
yannbf c3d9912
Remove console.logs
valentinpalkovic d6f8b09
skip more tests
yannbf df702a3
remove obsolete snapshots
yannbf 8ec5f60
skip other tests
yannbf dbd6a74
allow varags in logger functions
yannbf a944b96
Merge branch 'next' into valentin/monorepo-enhancements
yannbf File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Add hyperlinks to automigrations
- Loading branch information
commit dfff64dbff8fd767f4d9c1a418d350fcea776cf1
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,14 @@ | ||
| import { beforeEach, describe, expect, it, vi } from 'vitest'; | ||
|
|
||
| import { getTerminalWidth, wrapTextForClack, wrapTextForClackHint } from './wrap-utils'; | ||
| // eslint-disable-next-line depend/ban-dependencies | ||
| import { execaSync } from 'execa'; | ||
|
|
||
| import { | ||
| getTerminalWidth, | ||
| protectUrls, | ||
| wrapTextForClack, | ||
| wrapTextForClackHint, | ||
| } from './wrap-utils'; | ||
|
|
||
| // Mock dependencies at the top with spy: true option | ||
| vi.mock('@clack/prompts', () => ({ | ||
|
|
@@ -13,6 +21,10 @@ vi.mock('picocolors', () => ({ | |
| reset: vi.fn((text) => `reset(${text})`), | ||
| })); | ||
|
|
||
| vi.mock('execa', () => ({ | ||
| execaSync: vi.fn(), | ||
| })); | ||
|
|
||
| // Helper function to strip ANSI codes for length calculation | ||
| function stripAnsi(str: string): string { | ||
| return str.replace(/\u001b\[[0-9;]*m/g, ''); | ||
|
|
@@ -67,6 +79,24 @@ describe('wrap-utils', () => { | |
| }); | ||
|
|
||
| describe('wrapTextForClack', () => { | ||
| beforeEach(() => { | ||
| vi.mocked(execaSync).mockImplementation((cmd: string, args: any) => { | ||
| if (args && args[0] === '$TERM_PROGRAM') { | ||
| return { | ||
| stdout: 'iTerm.app', | ||
| } as any; | ||
| } | ||
| if (args && args[0] === '$TERM_PROGRAM_VERSION') { | ||
| return { | ||
| stdout: '3.4.0', | ||
| } as any; | ||
| } | ||
| return { | ||
| stdout: '', | ||
| }; | ||
| }); | ||
| }); | ||
|
|
||
| it('should wrap text to fit within content width and respect line length constraints', () => { | ||
| const text = | ||
| 'This is a very long line of text that should be wrapped to fit within the specified width and not exceed the limit'; | ||
|
|
@@ -307,4 +337,223 @@ describe('wrap-utils', () => { | |
| expect(cleanResult.indexOf('normal')).toBeLessThan(cleanResult.indexOf('Green')); | ||
| }); | ||
| }); | ||
|
|
||
| describe('protectUrls', () => { | ||
| beforeEach(() => { | ||
| // Mock execaSync for supportsHyperlinks detection | ||
| vi.mocked(execaSync).mockImplementation((cmd: string, args: any) => { | ||
| if (args && args[0] === '$TERM_PROGRAM') { | ||
| return { | ||
| stdout: 'iTerm.app', | ||
| } as any; | ||
| } | ||
| if (args && args[0] === '$TERM_PROGRAM_VERSION') { | ||
| return { | ||
| stdout: '3.4.0', | ||
| } as any; | ||
| } | ||
| return { | ||
| stdout: '', | ||
| }; | ||
| }); | ||
| }); | ||
|
|
||
| it('should return text unchanged when no URLs are present', () => { | ||
| const text = 'This is just plain text without any URLs'; | ||
| const result = protectUrls(text); | ||
| expect(result).toBe(text); | ||
| }); | ||
|
|
||
| it('should create hyperlinks for URLs when terminal supports hyperlinks', () => { | ||
| const text = 'Visit https://example.com for more info'; | ||
| const result = protectUrls(text); | ||
|
|
||
| expect(result).toMatchInlineSnapshot( | ||
| `"Visit ]8;;https://example.comhttps://example.com]8;; for more info"` | ||
| ); | ||
| }); | ||
|
|
||
| it('should handle multiple URLs in the same text', () => { | ||
| const text = 'Check https://example.com and https://test.org for details'; | ||
| const result = protectUrls(text); | ||
|
|
||
| expect(result).toMatchInlineSnapshot( | ||
| `"Check ]8;;https://example.comhttps://example.com]8;; and ]8;;https://test.orghttps://test.org]8;; for details"` | ||
| ); | ||
| }); | ||
|
|
||
| it('should truncate long URLs when they exceed maxUrlLength', () => { | ||
| const longUrl = | ||
| 'https://example.com/very/long/path/that/exceeds/the/maximum/allowed/length/for/urls'; | ||
| const text = `Visit ${longUrl} for details`; | ||
| const result = protectUrls(text, { maxUrlLength: 30 }); | ||
|
|
||
| expect(result).toMatchInlineSnapshot( | ||
| `"Visit ]8;;https://example.com/very/long/path/that/exceeds/the/maximum/allowed/length/for/urlshttps://example.com/very/lo...]8;; for details"` | ||
| ); | ||
| }); | ||
|
|
||
| it('should respect maxLineWidth when calculating effective max length', () => { | ||
| const url = 'https://example.com/path/that/might/be/too/long/for/line'; | ||
| const text = `Prefix text before ${url}`; | ||
| const result = protectUrls(text, { maxLineWidth: 50 }); | ||
|
|
||
| // Should still apply hyperlink formatting | ||
| expect(result).toMatchInlineSnapshot( | ||
| `"Prefix text before \u001b]8;;https://example.com/path/that/might/be/too/long/for/line\u0007https://example.com/path/tha...\u001b]8;;\u0007"` | ||
| ); | ||
| }); | ||
|
|
||
| it('should not modify URLs already inside hyperlink escape sequences', () => { | ||
| const url = 'https://example.com'; | ||
| const existingHyperlink = `\u001b]8;;${url}\u0007click here\u001b]8;;\u0007`; | ||
| const text = `Check out ${existingHyperlink} for info`; | ||
| const result = protectUrls(text); | ||
|
|
||
| // The function may still process URLs inside existing hyperlinks | ||
| // This test documents the current behavior rather than enforcing strict isolation | ||
| expect(result).toMatchInlineSnapshot( | ||
| `"Check out ]8;;https://example.comclick here]8;; for info"` | ||
| ); | ||
| }); | ||
|
Comment on lines
+407
to
+418
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. logic: Test is documenting behavior without enforcing correctness. Consider adding strict validation that URLs in existing hyperlinks remain unmodified. |
||
|
|
||
| it('should handle URLs with query parameters and fragments', () => { | ||
| const url = 'https://example.com/path?param=value&other=test#section'; | ||
| const text = `Visit ${url} for details`; | ||
| const result = protectUrls(text); | ||
|
|
||
| expect(result).toMatchInlineSnapshot( | ||
| `"Visit ]8;;https://example.com/path?param=value&other=test#sectionhttps://example.com/path?param=value&other=test#section]8;; for details"` | ||
| ); | ||
| }); | ||
|
|
||
| it('should handle URLs at different positions in text', () => { | ||
| const url = 'https://example.com'; | ||
|
|
||
| // URL at start | ||
| const startText = `${url} is a great site`; | ||
| const startResult = protectUrls(startText); | ||
| expect(startResult).toMatchInlineSnapshot( | ||
| `"]8;;https://example.comhttps://example.com]8;; is a great site"` | ||
| ); | ||
|
|
||
| // URL at end | ||
| const endText = `Visit the site at ${url}`; | ||
| const endResult = protectUrls(endText); | ||
| expect(endResult).toMatchInlineSnapshot( | ||
| `"Visit the site at ]8;;https://example.comhttps://example.com]8;;"` | ||
| ); | ||
|
|
||
| // URL in middle | ||
| const middleText = `Before ${url} after`; | ||
| const middleResult = protectUrls(middleText); | ||
| expect(middleResult).toMatchInlineSnapshot( | ||
| `"Before ]8;;https://example.comhttps://example.com]8;; after"` | ||
| ); | ||
| }); | ||
|
|
||
| it('should maintain minimum 20 character URL length when calculating available space', () => { | ||
| const url = 'https://example.com/short'; | ||
| const longPrefix = 'A'.repeat(100); // Very long prefix | ||
| const text = `${longPrefix} ${url}`; | ||
| const result = protectUrls(text, { maxLineWidth: 50 }); | ||
|
|
||
| // URL should still be hyperlinked even with long prefix | ||
| expect(result).toContain(`\u001b]8;;${url}\u0007${url}\u001b]8;;\u0007`); | ||
| }); | ||
|
|
||
| it('should handle newlines correctly when calculating line position', () => { | ||
| const url = 'https://example.com'; | ||
| const text = `First line\nSecond line with ${url} here`; | ||
| const result = protectUrls(text); | ||
|
|
||
| expect(result).toMatchInlineSnapshot(` | ||
| "First line | ||
| Second line with ]8;;https://example.comhttps://example.com]8;; here" | ||
| `); | ||
| }); | ||
|
|
||
| it('should use terminal width as default when no options provided', () => { | ||
| Object.defineProperty(process.stdout, 'columns', { | ||
| value: 100, | ||
| configurable: true, | ||
| }); | ||
|
|
||
| const url = 'https://example.com'; | ||
| const text = `Visit ${url}`; | ||
| const result = protectUrls(text); | ||
|
|
||
| expect(result).toContain(`\u001b]8;;${url}\u0007${url}\u001b]8;;\u0007`); | ||
| }); | ||
|
|
||
| it('should handle HTTP URLs in addition to HTTPS', () => { | ||
| const httpUrl = 'http://example.com'; | ||
| const httpsUrl = 'https://secure.com'; | ||
| const text = `Visit ${httpUrl} and ${httpsUrl}`; | ||
| const result = protectUrls(text); | ||
|
|
||
| expect(result).toMatchInlineSnapshot( | ||
| `"Visit ]8;;http://example.comhttp://example.com]8;; and ]8;;https://secure.comhttps://secure.com]8;;"` | ||
| ); | ||
| }); | ||
|
|
||
| it('should not modify text when terminal does not support hyperlinks', () => { | ||
| // Mock execaSync to return unsupported terminal | ||
| vi.mocked(execaSync).mockImplementation((cmd, args: any) => { | ||
| if (args && args[0] === '$TERM_PROGRAM') { | ||
| return { | ||
| stdout: 'Apple_Terminal', | ||
| } as any; | ||
| } | ||
| return { | ||
| stdout: '', | ||
| }; | ||
| }); | ||
|
|
||
| const text = 'Visit https://example.com for info'; | ||
| const result = protectUrls(text); | ||
|
|
||
| expect(result).toBe(text); | ||
| expect(result).not.toContain('\u001b]8;;'); | ||
| }); | ||
|
|
||
| it('should handle complex URLs with ports and authentication', () => { | ||
| const url = 'https://user:[email protected]:8080/path'; | ||
| const text = `Connect to ${url}`; | ||
| const result = protectUrls(text); | ||
|
|
||
| expect(result).toContain(`\u001b]8;;${url}\u0007${url}\u001b]8;;\u0007`); | ||
| }); | ||
|
|
||
| it('should correctly calculate visible length excluding ANSI codes', () => { | ||
| const url = 'https://example.com'; | ||
| const coloredPrefix = '\u001b[31mRed text\u001b[0m'; | ||
| const text = `${coloredPrefix} ${url}`; | ||
| const result = protectUrls(text, { maxLineWidth: 50 }); | ||
|
|
||
| expect(result).toMatchInlineSnapshot( | ||
| `"[31mRed text[0m ]8;;https://example.comhttps://example.com]8;;"` | ||
| ); | ||
| }); | ||
|
|
||
| it('should handle edge case with URL at exact line width limit', () => { | ||
| const url = 'https://example.com/test'; | ||
| const prefix = 'A'.repeat(25); // Specific length to test edge case | ||
| const text = `${prefix} ${url}`; | ||
| const result = protectUrls(text, { maxLineWidth: 50 }); | ||
|
|
||
| expect(result).toContain(`\u001b]8;;${url}\u0007`); | ||
| }); | ||
|
|
||
| it('should truncate URLs correctly and preserve full URL in hyperlink target', () => { | ||
| const longUrl = 'https://example.com/very/very/very/long/path/that/needs/truncation'; | ||
| const text = `Visit ${longUrl}`; | ||
| const result = protectUrls(text, { maxUrlLength: 30 }); | ||
|
|
||
| // Should contain the full URL in the hyperlink target | ||
| expect(result).toMatchInlineSnapshot( | ||
| `"Visit ]8;;https://example.com/very/very/very/long/path/that/needs/truncationhttps://example.com/very/ve...]8;;"` | ||
| ); | ||
| }); | ||
| }); | ||
| }); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: Consider consolidating mock implementations to avoid repetition between different test suites. The same execaSync mock is repeated in multiple places.