diff --git a/README.es.md b/README.es.md index 4fb86f93..4c2f8cac 100644 --- a/README.es.md +++ b/README.es.md @@ -204,7 +204,6 @@ npm run start -- -f -e # :bug: Bugs conocidos :bug: - A veces, el CLI se bloquea mientras un directorio se está borrando. -- Algunas terminales que no utilizan TTY (como git bash en Windows) no funcionan. - La ordenación, especialmente por rutas, puede ralentizar la terminal cuando haya muchos resultados al mismo tiempo. - A veces, los cálculos de tamaño son mayores de lo que deberían ser. - (RESUELTO) Problemas de rendimiento al hacer la búsqueda desde directorios de alto nivel (como / en Linux). diff --git a/README.md b/README.md index 66a6f5fc..8c9fe03c 100644 --- a/README.md +++ b/README.md @@ -279,7 +279,6 @@ You can check the basic API [here](./API.md) or on the web (comming soon). # :bug: Known bugs :bug: - Sometimes, CLI is blocked while folder is deleting. -- Some terminals that do not use TTY (like git bash in windows) do not work. - Sorting, especially by routes, can slow down the terminal when there are many results at the same time. - Sometimes, size calculations are higher than they should be. - (SOLVED) Performance issues when searching from high level directories (like / in linux). diff --git a/src/cli/cli.controller.ts b/src/cli/cli.controller.ts index 1472c625..4897c719 100644 --- a/src/cli/cli.controller.ts +++ b/src/cli/cli.controller.ts @@ -607,11 +607,6 @@ export class CliController { this.logger.error(INFO_MSGS.MIN_CLI_CLOMUNS); this.exitWithError(); } - if (!this.stdout.isTTY) { - this.uiService.print(INFO_MSGS.NO_TTY); - this.logger.error(INFO_MSGS.NO_TTY); - this.exitWithError(); - } } private checkFileRequirements(): void { diff --git a/src/cli/services/ui.service.ts b/src/cli/services/ui.service.ts index 4900a36e..f3c59d4c 100644 --- a/src/cli/services/ui.service.ts +++ b/src/cli/services/ui.service.ts @@ -7,7 +7,9 @@ export class UiService { uiComponents: BaseUi[] = []; setRawMode(set = true): void { - this.stdin.setRawMode(set); + if (this.stdin.isTTY) { + this.stdin.setRawMode(set); + } process.stdin.resume(); } diff --git a/src/constants/messages.constants.ts b/src/constants/messages.constants.ts index 4dd00417..f746e356 100644 --- a/src/constants/messages.constants.ts +++ b/src/constants/messages.constants.ts @@ -15,10 +15,6 @@ export const INFO_MSGS = { 'Oh no! The terminal is too narrow. Please, ' + 'enlarge it (This will be fixed in future versions. Disclose the inconveniences)', NEW_UPDATE_FOUND: 'New version found! npm i -g npkill for update.', - NO_TTY: - 'Oh no! Npkill does not support this terminal (TTY is required). This ' + - 'is a bug, which has to be fixed. Please try another command interpreter ' + - '(for example, CMD in windows)', NO_VALID_SORT_NAME: 'Invalid sort option. Available: path | size | last-mod', NO_VALID_SIZE_UNIT: 'Invalid size-unit option. Available: auto | mb | gb', STARTING: 'Initializing ', diff --git a/tests/cli/cli.controller.test.ts b/tests/cli/cli.controller.test.ts index 3e063df8..cfa41b74 100644 --- a/tests/cli/cli.controller.test.ts +++ b/tests/cli/cli.controller.test.ts @@ -196,8 +196,14 @@ describe('CliController test', () => { configServiceMock as unknown as ConfigService, ); - Object.defineProperty(process.stdout, 'columns', { value: 80 }); - Object.defineProperty(process.stdout, 'isTTY', { value: true }); + Object.defineProperty(process.stdout, 'columns', { + value: 80, + configurable: true, + }); + Object.defineProperty(process.stdout, 'isTTY', { + value: true, + configurable: true, + }); showHelpSpy = jest .spyOn(cliController, 'showHelp') @@ -398,5 +404,26 @@ describe('CliController test', () => { expect(exitWithErrorSpy).toHaveBeenCalledTimes(1); }); }); + + describe('TTY Handling', () => { + it('Should run normally even if stdout is NOT TTY', () => { + Object.defineProperty(process.stdout, 'isTTY', { + value: false, + configurable: true, + }); + cliController.init(); + expect(scanSpy).toHaveBeenCalledTimes(1); + }); + + it('Should exit if terminal is too small', () => { + Object.defineProperty(process.stdout, 'columns', { + value: 10, + configurable: true, + }); + const exitWithErrorSpy = spyMethod('exitWithError'); + cliController.init(); + expect(exitWithErrorSpy).toHaveBeenCalledTimes(1); + }); + }); }); }); diff --git a/tests/cli/services/ui.service.test.ts b/tests/cli/services/ui.service.test.ts new file mode 100644 index 00000000..1a990348 --- /dev/null +++ b/tests/cli/services/ui.service.test.ts @@ -0,0 +1,59 @@ +import { jest } from '@jest/globals'; +import { UiService } from '../../../src/cli/services/ui.service.js'; + +jest.mock('../../../src/dirname.js', () => { + return {}; +}); + +describe('UiService', () => { + let uiService: UiService; + let stdinMock: any; + let stdoutMock: any; + + beforeEach(() => { + stdinMock = { + isTTY: true, + setRawMode: jest.fn(), + resume: jest.fn(), + on: jest.fn(), + }; + stdoutMock = { + write: jest.fn(), + }; + + // Mock process.stdout and process.stdin + Object.defineProperty(process, 'stdin', { + value: stdinMock, + configurable: true, + }); + Object.defineProperty(process, 'stdout', { + value: stdoutMock, + configurable: true, + }); + + uiService = new UiService(); + // Inject the mocked stdin into the service instance as it's assigned in the property declaration + uiService.stdin = stdinMock; + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('setRawMode', () => { + it('should call setRawMode when stdin is TTY', () => { + uiService.setRawMode(true); + expect(stdinMock.setRawMode).toHaveBeenCalledWith(true); + expect(stdinMock.resume).toHaveBeenCalled(); + }); + + it('should NOT call setRawMode when stdin is NOT TTY', () => { + // update mock to simulate non-TTY + stdinMock.isTTY = false; + + uiService.setRawMode(true); + expect(stdinMock.setRawMode).not.toHaveBeenCalled(); + expect(stdinMock.resume).toHaveBeenCalled(); // Resume should still be called + }); + }); +});