diff --git a/src/__tests__/plugin.spec.ts b/src/__tests__/plugin.spec.ts index b3c1a03..dd2d85f 100644 --- a/src/__tests__/plugin.spec.ts +++ b/src/__tests__/plugin.spec.ts @@ -297,6 +297,43 @@ describe('CodeSizeAnalyzer', () => { expect(lastCallArgs[0]).toBe('\x1b[32m%s\x1b[0m'); expect(lastCallArgs[1]).toContain('MB'); }); + + it('should calculate percentage correctly when units differ', () => { + const originalBundle: BundleList = [ + ['test.js', { code: 'a'.repeat(500 * 1024) } as any] + ]; + + const obfuscatedBundle: BundleList = [ + ['test.js', { code: 'a'.repeat(2 * 1024 * 1024) } as any] + ]; + + analyzer.start(originalBundle); + analyzer.end(obfuscatedBundle); + + const lastCallArgs = logSpy.mock.lastCall; + expect(lastCallArgs[0]).toBe('\x1b[32m%s\x1b[0m'); + const result = lastCallArgs[1]; + + expect(result).toMatch(/\d+(\.\d+)?KB.*→.*\d+(\.\d+)?MB/); + expect(result).toMatch(/309\.\d+%/); + }); + + it('should handle zero division when calculating percentage', () => { + const emptyOriginalBundle: BundleList = []; + + const obfuscatedBundle: BundleList = [ + ['test.js', { code: 'console.log("test");' } as any] + ]; + + analyzer.start(emptyOriginalBundle); + analyzer.end(obfuscatedBundle); + + const lastCallArgs = logSpy.mock.lastCall; + expect(lastCallArgs[0]).toBe('\x1b[32m%s\x1b[0m'); + const result = lastCallArgs[1]; + + expect(result).toContain('0.00%'); + }); }); describe('is utils', () => { diff --git a/src/utils/index.ts b/src/utils/index.ts index d0efd84..49515cc 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -264,6 +264,8 @@ export class CodeSizeAnalyzer { private _log; private originalSize: SizeResult; private obfuscatedSize: SizeResult; + private originalBytes: { total: number; gzip: number }; + private obfuscatedBytes: { total: number; gzip: number }; private startTime: number; private endTime: number; @@ -271,6 +273,8 @@ export class CodeSizeAnalyzer { this._log = log; this.originalSize = this.createEmptySizeResult(); this.obfuscatedSize = this.createEmptySizeResult(); + this.originalBytes = { total: 0, gzip: 0 }; + this.obfuscatedBytes = { total: 0, gzip: 0 }; this.startTime = 0; this.endTime = 0; } @@ -284,16 +288,23 @@ export class CodeSizeAnalyzer { start(originalBundleList: BundleList): void { this.startTime = performance.now(); - this.originalSize = this.calculateBundleSize(originalBundleList); + const { size, bytes } = this.calculateBundleSize(originalBundleList); + this.originalSize = size; + this.originalBytes = bytes; } end(obfuscatedBundleList: BundleList): void { - this.obfuscatedSize = this.calculateBundleSize(obfuscatedBundleList); + const { size, bytes } = this.calculateBundleSize(obfuscatedBundleList); + this.obfuscatedSize = size; + this.obfuscatedBytes = bytes; this.endTime = performance.now(); this.logResult(); } - private calculateBundleSize(bundleList: BundleList): { original: FormatSizeResult; gzip: FormatSizeResult } { + private calculateBundleSize(bundleList: BundleList): { + size: { original: FormatSizeResult; gzip: FormatSizeResult }; + bytes: { total: number; gzip: number }; + } { const { totalSize, gzipSize } = bundleList.reduce( (acc, [, bundleItem]) => { if (bundleItem.code) { @@ -307,25 +318,29 @@ export class CodeSizeAnalyzer { ); return { - original: formatSize(totalSize), - gzip: formatSize(gzipSize), + size: { + original: formatSize(totalSize), + gzip: formatSize(gzipSize), + }, + bytes: { + total: totalSize, + gzip: gzipSize, + }, }; } private analyze(): string { - const { originalSize, obfuscatedSize } = this; + const { originalSize, obfuscatedSize, originalBytes, obfuscatedBytes } = this; const consume = formatTime(this.endTime - this.startTime); - const percentageIncrease = ( - ((obfuscatedSize.original.value - originalSize.original.value) / originalSize.original.value) - * 100 - ).toFixed(2); + const percentageIncrease = originalBytes.total > 0 + ? (((obfuscatedBytes.total - originalBytes.total) / originalBytes.total) * 100).toFixed(2) + : '0.00'; - const gzipPercentageIncrease = ( - ((obfuscatedSize.gzip.value - originalSize.gzip.value) / originalSize.gzip.value) - * 100 - ).toFixed(2); + const gzipPercentageIncrease = originalBytes.gzip > 0 + ? (((obfuscatedBytes.gzip - originalBytes.gzip) / originalBytes.gzip) * 100).toFixed(2) + : '0.00'; return `✓ obfuscated in ${consume} | 📦 ${originalSize.original.value}${originalSize.original.unit} (gzip: ${originalSize.gzip.value}${originalSize.gzip.unit}) → 🔒 ${obfuscatedSize.original.value}${obfuscatedSize.original.unit} (gzip: ${obfuscatedSize.gzip.value}${obfuscatedSize.gzip.unit}) | 📈 ${percentageIncrease}% (gzip: ${gzipPercentageIncrease}%)`; }