diff --git a/__tests__/optimize-imports-mocks.ts b/__tests__/optimize-imports-mocks.ts index d82c2c9..1093dfb 100644 --- a/__tests__/optimize-imports-mocks.ts +++ b/__tests__/optimize-imports-mocks.ts @@ -1,4 +1,4 @@ -export type TestCase = { input: string; expected: string }; +export type TestCase = { input: string; expected: string; noOfRuns?: number }; export const readmeExample: TestCase = { input: `import fs from 'fs'; @@ -97,3 +97,17 @@ if (environment.production) { enableProdMode(); }`, }; + +export const emptyNewLineSeparator: TestCase = { + noOfRuns: 2, + input: `import { Component, HostListener } from '@angular/core'; + import { Observable } from 'rxjs'; + import { MatDialogRef } from '@angular/material/dialog'; + + + import { AboutDialogBloc, AboutState } from './about-dialog.bloc';`, + expected: `import { Component, HostListener } from '@angular/core'; +import { Observable } from 'rxjs'; +import { MatDialogRef } from '@angular/material/dialog'; +import { AboutDialogBloc, AboutState } from './about-dialog.bloc';`, +}; diff --git a/__tests__/optimize-imports.spec.ts b/__tests__/optimize-imports.spec.ts index 8f3df32..8e0e202 100644 --- a/__tests__/optimize-imports.spec.ts +++ b/__tests__/optimize-imports.spec.ts @@ -2,7 +2,7 @@ import { actions, optimizeImports } from '@ic/conductor/optimize-imports'; import * as config from '@ic/config'; import fs from 'fs'; import { Config } from '@ic/types'; -import { readmeExample, comments, TestCase, codeBetweenImports } from './optimize-imports-mocks'; +import { readmeExample, comments, TestCase, codeBetweenImports, emptyNewLineSeparator } from './optimize-imports-mocks'; import { defaultConfig } from '@ic/defaultConfig'; jest.mock('fs'); @@ -15,16 +15,23 @@ describe('optimizeImports', () => { thirdPartyDependencies: new Set(['@angular/core', 'rxjs']), }; + let spy: jasmine.Spy; beforeEach(() => { - spyOn(config, 'getConfig').and.returnValue(basicConfig); + spy = spyOn(config, 'getConfig'); + spy.and.returnValue(basicConfig); (fs.existsSync as any).mockReturnValue(true); (fs.writeFileSync as any).mockClear(); }); - async function assertConductor({ expected, input }: TestCase) { + async function assertConductor({ expected, input, noOfRuns }: TestCase) { (fs.readFileSync as any).mockReturnValue(Buffer.from(input)); + let noOfRun = noOfRuns ?? 1; const file = 'test.ts'; - const result = await optimizeImports(file); + let result: string; + do { + result = await optimizeImports(file); + } while (--noOfRun > 0); + expect(fs.writeFileSync).toHaveBeenCalledWith(file, expected); return result; @@ -42,6 +49,11 @@ describe('optimizeImports', () => { await assertConductor(codeBetweenImports); }); + it('should work empty new line separator', async () => { + spy.and.returnValue({ ...basicConfig, separator: '' }); + await assertConductor(emptyNewLineSeparator); + }); + it('should not change conducted file', async () => { (fs.readFileSync as any).mockReturnValue(Buffer.from(readmeExample.expected)); const file = 'test.ts'; diff --git a/src/conductor/format-import-statements.ts b/src/conductor/format-import-statements.ts index 596d251..657bb59 100644 --- a/src/conductor/format-import-statements.ts +++ b/src/conductor/format-import-statements.ts @@ -27,5 +27,15 @@ function hasImports([, imports]: CategoryEntry) { } function toImportBlock([, imports]: CategoryEntry) { - return [...imports.values()].join('\n'); + return [...imports.values()].map((l) => trim(l, ' \n')).join('\n'); +} + +function escapeRegex(string: string) { + return string.replace(/[\[\](){}?*+\^$\\.|\-]/g, '\\$&'); +} + +function trim(input: string, characters: string) { + characters = escapeRegex(characters); + + return input.replace(new RegExp('^[' + characters + ']+|[' + characters + ']+$', 'g'), ''); }