Skip to content

Commit

Permalink
chore: consolidate formatting in amp-devcontainer-cpp (#582)
Browse files Browse the repository at this point in the history
* chore: consolidate formatting in amp-devcontainer-cpp

* chore: don't forcefully enable formatOnSave

* chore: fix xwin-cache

* test: add test for formatting

* test: make execute in terminal more robust

* test: revert fill on terminal; element is not an input

* test: look in the correct place for terminal output
  • Loading branch information
rjaegers authored Sep 27, 2024
1 parent 9d4297e commit cc9380c
Show file tree
Hide file tree
Showing 11 changed files with 398 additions and 46 deletions.
12 changes: 8 additions & 4 deletions .devcontainer/cpp/devcontainer-metadata-vscode.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,24 @@
"ms-vscode.cmake-tools@1.19.52",
"ms-vscode.cpptools@1.21.6",
"ms-vsliveshare.vsliveshare@1.0.5940",
"sonarsource.sonarlint-vscode@4.10.0",
"xaver.clang-format@1.9.0"
"sonarsource.sonarlint-vscode@4.10.0"
],
"settings": {
"C_Cpp.intelliSenseEngine": "disabled",
"C_Cpp.formatting": "clangFormat",
"clangd.arguments": [
"--query-driver=/opt/**/arm-none-eabi-*",
"--compile-commands-dir=${userHome}/.amp"
],
"cmake.copyCompileCommands": "${userHome}/.amp/compile_commands.json",
"cortex-debug.gdbPath": "gdb-multiarch",
"cortex-debug.objdumpPath": "arm-none-eabi-objdump",
"sonarlint.pathToCompileCommands": "/root/.amp/compile_commands.json"
"sonarlint.pathToCompileCommands": "/root/.amp/compile_commands.json",
"[c]": {
"editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd"
},
"[cpp]": {
"editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd"
}
}
}
}
Expand Down
66 changes: 44 additions & 22 deletions .devcontainer/cpp/e2e/features/pages/codespace.pom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,25 @@ export class CodespacePage {
await expect(this.page.getByRole('button', { name: 'Activating Extensions...' })).toBeHidden();
}

/**
* Executes the given commands in the command palette.
*
* This method waits for `prompt` to appear and then types `command` and presses Enter.
* When no prompt is given the default prompt is used.
*
* @param commands - The commands to execute in the command palette. It can be a single command or an array of commands.
*/
async executeFromCommandPalette(commands: CommandAndPrompt | CommandAndPrompt[]) {
await this.page.keyboard.press('Control+Shift+P');

for (const command of Array.isArray(commands) ? commands : [commands]) {
let prompt = this.page.getByPlaceholder(command.prompt || 'Type the name of a command to run');

await prompt.fill(`> ${command.command}`);
await prompt.press('Enter');
}
}

/**
* Executes the given commands in the terminal.
*
Expand All @@ -59,34 +78,15 @@ export class CodespacePage {
* @param commands - The commands to execute in the terminal. It can be a single command or an array of commands.
*/
async executeInTerminal(commands: string | string[]) {
await this.page.keyboard.press('Control+Shift+`');
await expect(this.page.locator('.terminal-wrapper.active')).toBeVisible();
await this.executeFromCommandPalette({ command: 'Terminal: Focus on Terminal View' });
await expect(this.page.locator('.terminal-widget-container')).toBeVisible();

for (const command of Array.isArray(commands) ? [...commands + 'exit'] : [commands, 'exit']) {
for (const command of Array.isArray(commands) ? commands : [commands]) {
await this.terminal.pressSequentially(command);
await this.terminal.press('Enter');
}
}

/**
* Executes the given commands in the command palette.
*
* This method waits for `prompt` to appear and then types `command` and presses Enter.
* When no prompt is given the default prompt is used.
*
* @param commands - The commands to execute in the command palette. It can be a single command or an array of commands.
*/
async executeFromCommandPalette(commands: CommandAndPrompt | CommandAndPrompt[]) {
await this.page.keyboard.press('Control+Shift+P');

for (const command of Array.isArray(commands) ? commands : [commands]) {
let prompt = this.page.getByPlaceholder(command.prompt || 'Type the name of a command to run');

await prompt.pressSequentially(command.command);
await prompt.press('Enter');
}
}

/**
* Opens the tab with the given name.
*
Expand All @@ -101,7 +101,29 @@ export class CodespacePage {
await expect(this.page.locator('[id="workbench.parts.editor"]')).toContainText(name);
}

async openCppFileInEditor(name: string) {
await this.openFileInEditor(name);
await expect(this.page.locator('[id="llvm-vs-code-extensions.vscode-clangd"]')).toContainText('clangd: idle', { timeout: 1 * 60 * 1000 });
}

async formatDocument() {
await this.executeFromCommandPalette({ command: 'Format Document' });
}

async saveDocument() {
await this.page.keyboard.press('Control+S');
}

async buildSelectedTarget() {
await this.page.getByRole('button', { name: 'Build the selected target' }).click();
}

async expectEditorContent(expected: RegExp) {
await expect(this.page.getByRole('code')).toContainText(expected);
}

async expectFileContentsToMatch(actual: string, expected: string) {
await this.executeInTerminal(`diff -s ${actual} ${expected}`);
await expect(this.page.locator('#terminal')).toContainText(`Files ${actual} and ${expected} are identical`);
}
}
12 changes: 12 additions & 0 deletions .devcontainer/cpp/e2e/features/static-dynamic-analysis.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Feature: Analyze source code using static and dynamic analysis

As a software craftsman
To maintain consistent, high-quality and bug-free code
Source code needs to be statically and dynamically analyzed

Scenario: Format source code according to a formatting style

Given the file "unformatted.cpp" is opened in the editor
When the active document is formatted
And the active document is saved
Then the contents of "unformatted.cpp" should match the contents of "formatted.cpp"
44 changes: 44 additions & 0 deletions .devcontainer/cpp/e2e/features/steps/codespace.steps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { expect } from "@playwright/test";
import { Given, When, Then } from "./fixtures";
import * as path from 'path';

Given("the default build configuration is selected", async () => {
// No-op
});

Given("the file {string} is opened in the editor", async ({ codespacePage }, file: string) => {
const fileExtension = path.extname(file).slice(1);

switch (fileExtension) {
case 'cpp':
await codespacePage.openCppFileInEditor(file);
break;
default:
await codespacePage.openFileInEditor(file);
}
});

When("the configuration {string} is built", async ({ codespacePage }, configuration: string) => {
await codespacePage.page.getByRole('button', { name: 'Build the selected target' }).click();
await codespacePage.page.getByLabel(configuration).locator('a').click();
});

When("the active document is formatted", async ({ codespacePage }) => {
await codespacePage.formatDocument();
});

When("the active document is saved", async ({ codespacePage }) => {
await codespacePage.saveDocument();
});

Then("the output should contain {string}", async ({ codespacePage }, expectedOutput: string) => {
await expect(codespacePage.outputPanel).toContainText(expectedOutput, { timeout: 5 * 60 * 1000 });
});

Then("the editor should contain {string}", async ({ codespacePage }, expectedContent: string) => {
await codespacePage.expectEditorContent(new RegExp(expectedContent));
});

Then("the contents of {string} should match the contents of {string}", async ({ codespacePage }, actual: string, expected: string) => {
await codespacePage.expectFileContentsToMatch(actual, expected);
});
15 changes: 0 additions & 15 deletions .devcontainer/cpp/e2e/features/steps/compilation.steps.ts

This file was deleted.

7 changes: 7 additions & 0 deletions .devcontainer/cpp/e2e/workspace/formatted.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include <algorithm>
#include <iostream>

int main() {
std::cout << "Hello World!" << std::endl;
return 0;
}
8 changes: 8 additions & 0 deletions .devcontainer/cpp/e2e/workspace/unformatted.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include <iostream>
#include <algorithm>

int main()
{
std::cout << "Hello World!" << std::endl;
return 0;
}
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ jobs:
with:
path: test/.xwin-cache
key: xwin-cache
restore-keys: |
xwin-cache
- name: Run Tests
run: |
set -Eeuo pipefail
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/prime-cache.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,4 @@ jobs:
- uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with:
path: test/.xwin-cache
key: xwin-cache
key: xwin-cache-${{ github.run_id }}
Loading

0 comments on commit cc9380c

Please sign in to comment.