From e9b69f7c1e9f23dc27dedc6f5fcdf9a719ce9505 Mon Sep 17 00:00:00 2001 From: "Charles-P. Clermont" Date: Fri, 10 Jan 2025 10:26:58 -0500 Subject: [PATCH] Run prettier on the code --- .../vscode-extension/src/node/extension.ts | 12 +- .../src/node/liquid_profiler.ts | 107 +++++++++++------- .../src/node/test/liquid_profiler.spec.ts | 59 +++++----- 3 files changed, 108 insertions(+), 70 deletions(-) diff --git a/packages/vscode-extension/src/node/extension.ts b/packages/vscode-extension/src/node/extension.ts index ed7502e8f..5bcffdc7c 100644 --- a/packages/vscode-extension/src/node/extension.ts +++ b/packages/vscode-extension/src/node/extension.ts @@ -38,11 +38,13 @@ export async function activate(context: ExtensionContext) { ); context.subscriptions.push( commands.registerCommand('shopifyLiquid.openPreview', async () => { - const config = new Config({projectName: 'shopify-cli-theme-conf'}); + const config = new Config({ projectName: 'shopify-cli-theme-conf' }); const storeUrl = config.get('themeStore'); if (!storeUrl) { - window.showErrorMessage('Make sure Shopify is CLI is available in your environment and authenticated'); + window.showErrorMessage( + 'Make sure Shopify is CLI is available in your environment and authenticated', + ); return; } @@ -59,10 +61,12 @@ export async function activate(context: ExtensionContext) { try { await liquidProfiler.showProfileForUrl(url); } catch (error) { - window.showErrorMessage('Could not establish a profile for this URL. Check that you can execute `shopify theme profile` in your terminal'); + window.showErrorMessage( + 'Could not establish a profile for this URL. Check that you can execute `shopify theme profile` in your terminal', + ); } } - }) + }), ); await startServer(context); diff --git a/packages/vscode-extension/src/node/liquid_profiler.ts b/packages/vscode-extension/src/node/liquid_profiler.ts index 6d7a25d2a..6b5924e39 100644 --- a/packages/vscode-extension/src/node/liquid_profiler.ts +++ b/packages/vscode-extension/src/node/liquid_profiler.ts @@ -1,4 +1,15 @@ -import { Disposable, ExtensionContext, Uri, ViewColumn, WebviewPanel, window, workspace, Range, DecorationOptions, Position } from 'vscode'; +import { + Disposable, + ExtensionContext, + Uri, + ViewColumn, + WebviewPanel, + window, + workspace, + Range, + DecorationOptions, + Position, +} from 'vscode'; import * as path from 'node:path'; import { execSync } from 'node:child_process'; @@ -21,9 +32,9 @@ export class LiquidProfiler { margin: '0 0 1rem 0', textDecoration: 'none', }, - rangeBehavior: 1 // DecorationRangeBehavior.ClosedOpen + rangeBehavior: 1, // DecorationRangeBehavior.ClosedOpen }); - + private lineDecorationType = window.createTextEditorDecorationType({ backgroundColor: 'rgba(173, 216, 230, 0.2)', border: '1px solid rgba(173, 216, 230, 0.5)', @@ -53,19 +64,16 @@ export class LiquidProfiler { this._panel.title = `Liquid Profile: ${url}`; this._panel.webview.html = ''; } else { - this._panel = window.createWebviewPanel( - 'liquidProfile', - `Liquid Profile: ${url}`, - column, - { - enableScripts: true, - // Allow files in the user's workspace (.tmp directory) to be used as local resources - localResourceRoots: [ - ...(workspace.workspaceFolders ? workspace.workspaceFolders.map(folder => folder.uri) : []), - Uri.file(this._context.asAbsolutePath(path.join('dist', 'node', 'speedscope'))) - ] - } - ); + this._panel = window.createWebviewPanel('liquidProfile', `Liquid Profile: ${url}`, column, { + enableScripts: true, + // Allow files in the user's workspace (.tmp directory) to be used as local resources + localResourceRoots: [ + ...(workspace.workspaceFolders + ? workspace.workspaceFolders.map((folder) => folder.uri) + : []), + Uri.file(this._context.asAbsolutePath(path.join('dist', 'node', 'speedscope'))), + ], + }); this._panel.onDidDispose(() => this.dispose(), null, this._disposables); } @@ -78,7 +86,9 @@ export class LiquidProfiler { } private async _getSpeedscopeHtml(profileContents: string) { - const indexHtmlPath = Uri.file(this._context.asAbsolutePath(path.join('dist', 'node', 'speedscope', 'index.html'))); + const indexHtmlPath = Uri.file( + this._context.asAbsolutePath(path.join('dist', 'node', 'speedscope', 'index.html')), + ); let htmlContent = Buffer.from(await workspace.fs.readFile(indexHtmlPath)).toString('utf8'); // Convert local resource paths to vscode-resource URIs, and replace the paths in the HTML content @@ -96,8 +106,12 @@ export class LiquidProfiler { const tmpFile = path.join(tmpDir!, '.tmp', 'profile.json'); await workspace.fs.writeFile(Uri.file(tmpFile), Buffer.from(profileContents)); const tmpUri = this._panel!.webview.asWebviewUri(Uri.file(tmpFile)); - htmlContent = htmlContent.replace('', ``); + htmlContent = htmlContent.replace( + '', + ``, + ); return htmlContent; } @@ -116,7 +130,7 @@ export class LiquidProfiler { /** * Calculate the execution times for each file and line in the profile. * @param profile - The parsed profile data. - * @returns An object containing two maps: + * @returns An object containing two maps: * fileExecutionTimes: Map - The execution time for each file. * lineExecutionTimes: Map - The execution time for each line. */ @@ -125,7 +139,7 @@ export class LiquidProfiler { const lineExecutionTimes = new Map(); const openEvents = new Map(); - profile.profiles[0].events.forEach(event => { + profile.profiles[0].events.forEach((event) => { const frameId = event.frame; const frame = profile.shared.frames[frameId]; @@ -136,7 +150,10 @@ export class LiquidProfiler { if (startTime !== undefined) { const duration = event.at - startTime; - if (frame.file && (frame.file.startsWith('sections/') || frame.file.startsWith('snippets/'))) { + if ( + frame.file && + (frame.file.startsWith('sections/') || frame.file.startsWith('snippets/')) + ) { let current = lineExecutionTimes.get(frame) || 0; lineExecutionTimes.set(frame, current + duration); @@ -169,8 +186,8 @@ export class LiquidProfiler { const { fileExecutionTimes, lineExecutionTimes } = this.calculateExecutionTimes(parsedProfile); - // Check if there are any workspace folders. - // TODO: Is this necessary? + // Check if there are any workspace folders. + // TODO: Is this necessary? const workspaceFolders = workspace.workspaceFolders; if (!workspaceFolders) { console.error('[Liquid Profiler] No workspace folders found'); @@ -193,8 +210,8 @@ export class LiquidProfiler { after: { contentText: ` (File) ⏱️ ${(duration / 1000000).toFixed(2)}ms`, color: this.getColorForDuration(duration), - } - } + }, + }, }; // Store the file-level decoration. @@ -204,15 +221,24 @@ export class LiquidProfiler { // Store the paths it's been applied to in a set. const appliedPaths = new Set(); for (const editor of visibleEditors) { - if (editor.document.uri.fsPath === uri.fsPath && !appliedPaths.has(editor.document.uri.fsPath)) { - console.log(`[Liquid Profiler] Applying file decoration for ${liquidFile} (${(duration / 1000000).toFixed(2)}ms) + if ( + editor.document.uri.fsPath === uri.fsPath && + !appliedPaths.has(editor.document.uri.fsPath) + ) { + console.log(`[Liquid Profiler] Applying file decoration for ${liquidFile} (${( + duration / 1000000 + ).toFixed(2)}ms) `); editor.setDecorations(this.fileDecorationType, [decoration]); appliedPaths.add(editor.document.uri.fsPath); } } - console.log(`[Liquid Profiler] Created file decoration for ${liquidFile} (${(duration / 1000000).toFixed(2)}ms)`); + console.log( + `[Liquid Profiler] Created file decoration for ${liquidFile} (${( + duration / 1000000 + ).toFixed(2)}ms)`, + ); } catch (err) { console.error(`[Liquid Profiler] Error creating file decoration for ${fullPath}:`, err); } @@ -223,19 +249,19 @@ export class LiquidProfiler { try { const uri = Uri.file(path.join(rootPath, `${frame.file}.liquid`)); const document = await workspace.openTextDocument(uri); - // If frame.name starts with 'variable:', then scan the line for the variable name after "variable:" and find the + // If frame.name starts with 'variable:', then scan the line for the variable name after "variable:" and find the // range immediately after the variable name to apply the decoration to let range: Range | undefined; if (frame.name.startsWith('variable:') || frame.name.startsWith('tag:')) { - const variableName = frame.name.split('variable:')[1] || frame.name.split('tag:')[1]; + const variableName = frame.name.split('variable:')[1] || frame.name.split('tag:')[1]; const line = document.lineAt(frame.line - 1); - const variableRange = line.text.indexOf(variableName);// 7 + const variableRange = line.text.indexOf(variableName); // 7 if (variableRange !== -1) { // Create range that covers the variable name itself using explicit positions range = new Range( new Position(line.lineNumber, variableRange), - new Position(line.lineNumber, variableRange + variableName.length) + new Position(line.lineNumber, variableRange + variableName.length), ); } else { // Fallback to full line if variable name not found @@ -249,16 +275,18 @@ export class LiquidProfiler { } const decoration: DecorationOptions = { range: range!, - renderOptions: { after: { contentText: ` ⏱️ ${(duration / 1000000).toFixed(2)}ms` } } + renderOptions: { after: { contentText: ` ⏱️ ${(duration / 1000000).toFixed(2)}ms` } }, }; // Store the decoration in a map where the key is the file path and the value is an array of decorations const fileDecorations = this._decorations.get(uri.fsPath) || []; fileDecorations.push(decoration); this._decorations.set(uri.fsPath, fileDecorations); - } catch (err) { - console.error(`[Liquid Profiler] Error creating line decoration for ${frame.file}:${frame.line}:`, err); + console.error( + `[Liquid Profiler] Error creating line decoration for ${frame.file}:${frame.line}:`, + err, + ); } } @@ -272,7 +300,7 @@ export class LiquidProfiler { // Add listener for active editor changes this._context.subscriptions.push( - window.onDidChangeActiveTextEditor(editor => { + window.onDidChangeActiveTextEditor((editor) => { if (editor) { const decorations = this._decorations.get(editor.document.uri.fsPath); if (decorations) { @@ -282,7 +310,7 @@ export class LiquidProfiler { editor.setDecorations(this.fileDecorationType, []); } } - }) + }), ); } @@ -292,7 +320,7 @@ export class LiquidProfiler { if (ms < 10) { // Fast: Green return '#4caf50'; - } + } if (ms < 50) { // Medium: Yellow return '#ffc107'; @@ -325,4 +353,3 @@ export class LiquidProfiler { } } } - diff --git a/packages/vscode-extension/src/node/test/liquid_profiler.spec.ts b/packages/vscode-extension/src/node/test/liquid_profiler.spec.ts index b3a8cb6d8..6bf3529e8 100644 --- a/packages/vscode-extension/src/node/test/liquid_profiler.spec.ts +++ b/packages/vscode-extension/src/node/test/liquid_profiler.spec.ts @@ -25,17 +25,16 @@ vi.mock('node:child_process', () => ({ describe('LiquidProfiler', () => { let profiler: LiquidProfiler; - + beforeEach(() => { const mockContext = { subscriptions: [], asAbsolutePath: (path: string) => path, } as unknown as ExtensionContext; - + profiler = new LiquidProfiler(mockContext); }); - describe('getProfileContents', () => { it('successfully retrieves profile content', () => { const mockJson = '{"profiles":[{"events":[]}]}'; @@ -361,35 +360,43 @@ describe('LiquidProfiler', () => { const executionTimes = profiler['calculateExecutionTimes'](profile); expect(executionTimes).toEqual({ - 'fileExecutionTimes': new Map([ - ['sections/single-collection.liquid', 949434], + fileExecutionTimes: new Map([ + ['sections/single-collection.liquid', 949434], ['snippets/collection-item.liquid', 90944], ]), - 'lineExecutionTimes': new Map([ - [{ - file: 'sections/single-collection', - line: 7, - name: 'variable:\'favicon.png\' | asset_url', - }, 249384], - [{ - file: 'sections/single-collection', - line: 13, - name: 'variable:child.system.url', - }, 700050], - [{ - file: 'snippets/collection-item', - line: 15, - name: 'variable:child.name', - }, 90944], - ]) + lineExecutionTimes: new Map([ + [ + { + file: 'sections/single-collection', + line: 7, + name: "variable:'favicon.png' | asset_url", + }, + 249384, + ], + [ + { + file: 'sections/single-collection', + line: 13, + name: 'variable:child.system.url', + }, + 700050, + ], + [ + { + file: 'snippets/collection-item', + line: 15, + name: 'variable:child.name', + }, + 90944, + ], + ]), }); }); it('handles invalid profile data gracefully', async () => { const invalidProfileData = 'invalid json'; - - await expect(profiler['processAndShowDecorations'](invalidProfileData)) - .rejects.toThrow(); + + await expect(profiler['processAndShowDecorations'](invalidProfileData)).rejects.toThrow(); }); }); -}); \ No newline at end of file +});