Add expansion, inheritance, include tests (#4137)

* Move the presets tests to integration tests.

These tests aren't true 'unit' tests by definition, so moving them to
integration.
Also, added include and CMakePresets/CMakeUserPresets tests.

* add inheritance and expansion and override tests

* fix formatting of test file

* fix linter issues

* fix lint issues

* fix path

* make tests better across platform

* fix lint
This commit is contained in:
Garrett Campbell 2024-11-06 06:34:12 -08:00 коммит произвёл GitHub
Родитель 781a5a6e9b
Коммит f47c79f5e0
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
11 изменённых файлов: 1271 добавлений и 835 удалений

5
.github/workflows/ci-main-linux.yml поставляемый
Просмотреть файл

@ -56,6 +56,11 @@ jobs:
with:
run: yarn unitTests
- name: Run integration tests
uses: GabrielBB/xvfb-action@v1.6
with:
run: yarn integrationTests
- name: Run successful-build test
uses: GabrielBB/xvfb-action@v1.6
with:

3
.github/workflows/ci-main-mac.yml поставляемый
Просмотреть файл

@ -57,6 +57,9 @@ jobs:
- name: Run unit tests
run: yarn unitTests
- name: Run integration tests
run: yarn integrationTests
- name: Run single root test
run: yarn endToEndTestsSingleRoot

3
.github/workflows/ci-main.win.yml поставляемый
Просмотреть файл

@ -54,6 +54,9 @@ jobs:
- name: Run unit tests
run: yarn unitTests
- name: Run integration tests
run: yarn integrationTests
- name: Run successful-build test
run: yarn endToEndTestsSuccessfulBuild

26
.vscode/launch.json поставляемый
Просмотреть файл

@ -34,7 +34,7 @@
"outFiles": [
"${workspaceFolder}/out/*",
"${workspaceFolder}/out/src/**",
"${workspaceFolder}/out/test/*",
"${workspaceFolder}/out/test/**",
"${workspaceFolder}/out/test/unit-tests/**",
],
"env": {
@ -44,6 +44,30 @@
},
"preLaunchTask": "Pretest"
},
{
"name": "Run Integration Tests",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"${workspaceFolder}/test/integration-tests",
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/out/test/integration-tests/index"
],
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/out/*",
"${workspaceFolder}/out/src/**",
"${workspaceFolder}/out/test/**",
"${workspaceFolder}/out/test/integration-tests/**",
],
"env": {
"CMT_TESTING": "1",
"CMT_QUIET_CONSOLE": "1",
"TEST_FILTER": ".*"
},
"preLaunchTask": "Pretest"
},
{
"name": "Run successful-build Tests",
"type": "extensionHost",

Просмотреть файл

@ -3692,6 +3692,7 @@
"lint": "gulp lint",
"smokeTests": "yarn run pretest && node ./out/test/smoke/badProject/runTest.js && node ./out/test/smoke/goodProject/runTest.js && node ./out/test/smoke/noCtest/runTest.js",
"unitTests": "yarn run pretest && node ./out/test/unit-tests/runTest.js",
"integrationTests": "yarn run pretest && node ./out/test/integration-tests/runTest.js",
"endToEndTestsSuccessfulBuild": "yarn run pretest && node ./out/test/end-to-end-tests/successful-build/runTest.js",
"endToEndTestsSingleRoot": "yarn run pretest && node ./out/test/end-to-end-tests/single-root-UI/runTest.js",
"endToEndTestsMultiRoot": "yarn run pretest && node ./out/test/end-to-end-tests/multi-root-UI/runTest.js",

Просмотреть файл

@ -0,0 +1,54 @@
// eslint-disable-next-line import/no-unassigned-import
import 'module-alias/register';
import * as path from 'path';
import * as Mocha from 'mocha';
import * as glob from 'glob';
import { Logger } from '@cmt/logging';
export function run(): Promise<void> {
// Create the mocha test
const mocha = new Mocha({
ui: 'tdd',
color: true
});
const testsRoot = __dirname;
return new Promise((c, e) => {
glob('**/*.test.js', { cwd: testsRoot }, (err, files) => {
if (err) {
return e(err);
}
// Add files to the test suite
const regex = process.env.TEST_FILTER ? new RegExp(process.env.TEST_FILTER) : /.*/;
files.forEach(f => {
if (regex.test(f)) {
mocha.addFile(path.resolve(testsRoot, f));
}
});
try {
// Run the mocha test
mocha.timeout(100000);
// Log the name of each test before it starts.
const beforeEach: Mocha.Func = function (this: Mocha.Context, done: Mocha.Done) {
Logger.logTestName(this.currentTest?.parent?.title, this.currentTest?.title);
done();
};
mocha.rootHooks({beforeEach});
mocha.run(failures => {
if (failures > 0) {
e(new Error(`${failures} tests failed.`));
} else {
c();
}
});
} catch (err) {
e(err);
}
});
});
}

Просмотреть файл

@ -0,0 +1,18 @@
{
"version": 3,
"configurePresets": [
{
"name": "default",
"environment": {
"PATH": "C:\\msys64\\ucrt64\\bin;$penv{PATH}"
}
},
{
"name": "empty"
},
{
"name": "custom",
"inherits": [ "empty", "default" ]
}
]
}

Просмотреть файл

@ -0,0 +1,140 @@
{
"version": 3,
"cmakeMinimumRequired": {
"major": 3,
"minor": 21,
"patch": 0
},
"configurePresets": [
{
"name": "default",
"displayName": "Default",
"description": "Default config, uses system default compiler",
"binaryDir": "${sourceDir}/build/${presetName}",
"generator": "Ninja Multi-Config",
"cacheVariables": {
"CMAKE_EXPORT_COMPILE_COMMANDS": true,
"BUILD_TOOLS": false
}
},
{
"name": "MSVC",
"displayName": "MSVC",
"description": "Use the Visual Studio compiler",
"inherits": "default",
"cacheVariables": {
"CMAKE_CXX_COMPILER": "cl",
"CMAKE_C_COMPILER": "cl"
},
"architecture": {
"value": "x64",
"strategy": "external"
},
"toolset": {
"value": "host=x64",
"strategy": "external"
}
},
{
"name": "tools",
"displayName": "tools",
"description": "Compile with tools (requires Qt)",
"inherits": "default",
"cacheVariables": {
"BUILD_TOOLS": true
}
},
{
"name": "tools-MSVC",
"displayName": "tools (MSVC)",
"description": "Compile with tools (requires Qt) using MSVC",
"inherits": ["tools", "MSVC"]
}
],
"buildPresets": [
{
"name": "debug",
"displayName": "Debug",
"description": "Build with debug information",
"configurePreset": "default",
"configuration": "Debug"
},
{
"name": "release",
"displayName": "Release",
"description": "Optimized build without debug information",
"configurePreset": "default",
"configuration": "Release"
},
{
"name": "RelWithDebInfo",
"displayName": "RelWithDebInfo",
"description": "Optimized build with debug information",
"configurePreset": "default",
"configuration": "RelWithDebInfo"
},
{
"name": "MSVC-debug",
"displayName": "Debug",
"description": "Build with debug information",
"configurePreset": "MSVC",
"configuration": "Debug"
},
{
"name": "MSVC-release",
"displayName": "Release",
"description": "Optimized build without debug information",
"configurePreset": "MSVC",
"configuration": "Release"
},
{
"name": "MSVC-RelWithDebInfo",
"displayName": "RelWithDebInfo",
"description": "Optimized build with debug information",
"configurePreset": "MSVC",
"configuration": "RelWithDebInfo"
},
{
"name": "tools-debug",
"displayName": "Debug (Tools)",
"description": "Build with debug information and tools",
"configurePreset": "tools",
"configuration": "Debug"
},
{
"name": "tools-release",
"displayName": "Release (Tools)",
"description": "Optimized build with tools",
"configurePreset": "tools",
"configuration": "Release"
},
{
"name": "tools-RelWithDebInfo",
"displayName": "RelWithDebInfo (Tools)",
"description": "Optimized build with debug information and tools",
"configurePreset": "tools",
"configuration": "RelWithDebInfo"
},
{
"name": "tools-MSVC-debug",
"displayName": "Debug (MSVC: Tools)",
"description": "Build with debug information and tools using MSVC",
"configurePreset": "tools-MSVC",
"configuration": "Debug"
},
{
"name": "tools-MSVC-release",
"displayName": "Release (MSVC: Tools)",
"description": "Optimized build with tools using MSVC",
"configurePreset": "tools-MSVC",
"configuration": "Release"
},
{
"name": "tools-MSVC-RelWithDebInfo",
"displayName": "RelWithDebInfo (MSVC: Tools)",
"description": "Optimized build with debug information and tools using MSVC",
"configurePreset": "tools-MSVC",
"configuration": "RelWithDebInfo"
}
]
}

Просмотреть файл

@ -0,0 +1,986 @@
import { ExpansionErrorHandler } from "@cmt/expand";
import { PresetsFile } from "@cmt/presets/preset";
import { PresetsParser } from "@cmt/presets/presetsParser";
import { expect } from "@test/util";
import * as fs from "fs";
import * as preset from "@cmt/presets/preset";
import * as path from "path";
import * as lodash from "lodash";
/**
* This test suite is designed specifically for testing the validation of a CMake Presets file.
* This specifically means that we are testing the existence of fields in the presets file based on what is supported for each
* presets version.
* This suite holds integration tests for the PresetsParser class that is responsible for validating, expanding, and including presets files.
* TODO: It might be more clear to break this up into multiple test suites. This could be a suite per version of Presets, or a suite per validation/inclusion/expansion, etc.
* In order to do this, it might be beneficial to create a helper class so we don't duplicate the setup code.
* TODO: It might be wise to consider having actual these tests based on a file that is in the repo, not just created on the fly as
* this could make it easier for integration tests and/or e2e tests.
*/
suite('Presets validation, inclusion, and expansion tests', () => {
let workspaceFolder: string;
let sourceDirectory: string;
let folderPath: string;
let presetsFileVersionErrors: string[] = [];
let presetsFileErrors: string[] = [];
let presetsParser: PresetsParser;
suiteSetup(async function (this: Mocha.Context) {
this.timeout(100000);
workspaceFolder = __dirname;
sourceDirectory = workspaceFolder;
folderPath = sourceDirectory;
presetsParser = new PresetsParser(
folderPath,
sourceDirectory,
workspaceFolder,
async (_path: string, _errors: ExpansionErrorHandler) => {
_errors.errorList.forEach((error) => {
presetsFileErrors.push(error[0]);
});
},
async (_file: string) => {
presetsFileVersionErrors.push(`Version error in ${_file}`);
},
(_filePath: string) => {
console.log("Modifying the collection for the Problems pane, not needed in this unit test");
},
(_file: PresetsFile | undefined) => {
console.log("Presets file handler");
},
(_file: PresetsFile | undefined) => {
console.log("User Presets file handler");
}
);
});
setup(async function (this: Mocha.Context) {
this.timeout(100000);
presetsFileVersionErrors = [];
presetsFileErrors = [];
});
suite('CMake Presets version validation', () => {
test('Validate that we fail on CMakePresets version 1', async () => {
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify({
"version": 1,
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja",
"binaryDir": "${workspaceFolder}/build"
}
]
}
));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileVersionErrors).to.have.lengthOf(1);
}).timeout(100000);
/**
* TODO: We need improvements in the code to ensure that we're requiring `binaryDir` in version 2.
* Test version 2 of CMake Prests.
* We want to ensure that we're requiring `binaryDir`.
* `installDir`, `condition`, `toolchainFile` are not supported in version 2.
*/
/* test('Validate version 2 CMakePresets, requires binaryDir', async () => {
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify({
"version": 2,
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja"
}
]
}
));
await presetsParser.resetPresetsFiles(
(_f, p) => (presetsContainer.expandedPresets = p),
(_f, p) => (presetsContainer.expandedUserPresets = p),
(_f, p) => (presetsContainer.presetsPlusIncluded = p),
(_f, p) => (presetsContainer.userPresetsPlusIncluded = p),
(_f, p) => (presetsContainer.originalPresets = p),
(_f, p) => (presetsContainer.originalUserPresets = p),
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(1);
expect(presetsFileErrors.filter((e) => e.includes("binaryDir"))).to.have.lengthOf(1);
expect(presetsContainer.expandedPresets).to.be.undefined;
expect(presetsContainer.expandedUserPresets).to.be.undefined;
expect(presetsContainer.presetsPlusIncluded).to.be.undefined;
expect(presetsContainer.userPresetsPlusIncluded).to.be.undefined;
}).timeout(100000);*/
/**
* Test version 2 of CMake Prests.
* Ensure that we're validating and that `installDir`, `condition`, and `toolchainFile` aren't allowed.
*/
test('Validate version 2 CMakePresets, requires binaryDir', async () => {
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify({
"version": 2,
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolchainFile": ""
}
]
}
));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(4);
expect(presetsFileErrors.filter((e) => e.includes("should NOT have additional properties: installDir"))).to.have.lengthOf(1);
expect(presetsFileErrors.filter((e) => e.includes("should NOT have additional properties: condition"))).to.have.lengthOf(1);
expect(presetsFileErrors.filter((e) => e.includes("should NOT have additional properties: toolchainFile"))).to.have.lengthOf(1);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(0);
}).timeout(100000);
const v3SupportedPresets: any = {
"version": 3,
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolchainFile": ""
}
]
};
/**
* Test validation of version 3 of CMake Prests.
* Ensure that `installDir` and `condition` are accepted.
*
* Then, add add `include` and `buildPresets with `resolvePackageReference`, confirm that `include` and `resolvePackageReference` are not allowed.
*/
test('Validate version 3 CMakePresets', async () => {
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify(v3SupportedPresets));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(0);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(1);
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify({
"version": 3,
"include": ["test.json"],
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolchainFile": ""
}
],
"buildPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"cleanFirst": true,
"resolvePackageReferences": "on"
}
]
}
));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(3);
expect(presetsFileErrors.filter((e) => e.includes("should NOT have additional properties: include"))).to.have.lengthOf(1);
expect(presetsFileErrors.filter((e) => e.includes("should NOT have additional properties: resolvePackageReference"))).to.have.lengthOf(1);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(0);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(0);
}).timeout(100000);
/**
* First test that the `include` and `resolvePackageReferences` fields are allowed in version 4.
* Then, test that fields only allowed in 5 aren't supported, by adding a testPreset with the `testOutputTrunction` field added.
*/
test('Validate version 4 CMakePresets', async () => {
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify({
"version": 4,
"include": ["test.json"],
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolchainFile": ""
}
],
"buildPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"cleanFirst": true,
"resolvePackageReferences": "on"
}
]
}
));
fs.writeFileSync(path.join(presetsParser.presetsPath, "..", "test.json"),
JSON.stringify({
"version": 4,
"configurePresets": [
{
"name": "blah",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolchainFile": ""
}
]
}
));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(0);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(2);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(1);
// Remove the include.
fs.rmSync(path.join(presetsParser.presetsPath, "..", "test.json"));
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify({
"version": 4,
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolchainFile": ""
}
],
"buildPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"cleanFirst": true,
"resolvePackageReferences": "on"
}
],
"testPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"output": {
"testOutputTruncation": "tail"
}
}
]
}
));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(2);
expect(presetsFileErrors.filter((e) => e.includes("should NOT have additional properties: testOutputTruncation"))).to.have.lengthOf(1);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(0);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(0);
}).timeout(100000);
/**
* First test that the `testOutputTruncation field is allowed in version 5.
*/
test('Validate version 5 CMakePresets', async () => {
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify({
"version": 5,
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolchainFile": ""
}
],
"buildPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"cleanFirst": true,
"resolvePackageReferences": "on"
}
],
"testPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"output": {
"testOutputTruncation": "tail"
}
}
]
}
));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(0);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(1);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(1);
expect(preset.testPresets(sourceDirectory).length).to.be.equal(1);
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify({
"version": 5,
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolchainFile": ""
}
],
"buildPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"cleanFirst": true,
"resolvePackageReferences": "on"
}
],
"testPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"output": {
"testOutputTruncation": "tail"
}
}
],
"packagePresets": [
{
"name": "x64-debug-package"
}
],
"workflowPresets": [
{
"name": "x64-debug-workflow",
"steps": [
{
"type": "configure",
"name": "x64-debug"
}
]
}
]
}
));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(3);
expect(presetsFileErrors.filter((e) => e.includes("should NOT have additional properties: packagePresets"))).to.have.lengthOf(1);
expect(presetsFileErrors.filter((e) => e.includes("should NOT have additional properties: workflowPresets"))).to.have.lengthOf(1);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(0);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(0);
expect(preset.testPresets(sourceDirectory).length).to.be.equal(0);
expect(preset.packagePresets(sourceDirectory).length).to.be.equal(0);
expect(preset.workflowPresets(sourceDirectory).length).to.be.equal(0);
}).timeout(100000);
const v6SupportedPresets: any = {
"version": 6,
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolchainFile": ""
}
],
"buildPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"cleanFirst": true,
"resolvePackageReferences": "on"
}
],
"testPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"output": {
"testOutputTruncation": "tail"
}
}
],
"packagePresets": [
{
"name": "x64-debug-package"
}
],
"workflowPresets": [
{
"name": "x64-debug-workflow",
"steps": [
{
"type": "configure",
"name": "configure"
}
]
}
]
};
/**
* Validate the `packagePresets` and `workflowPresets` are supported in Presets v6.
* Then, confirm that the `trace` object isn't allowed in v6, as it was introduced in v7
*/
test('Validate version 6 CMakePresets', async () => {
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify(v6SupportedPresets));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(0);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(1);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(1);
expect(preset.testPresets(sourceDirectory).length).to.be.equal(1);
expect(preset.packagePresets(sourceDirectory).length).to.be.equal(1);
expect(preset.workflowPresets(sourceDirectory).length).to.be.equal(1);
const v6AddedTrace = lodash.cloneDeep(v6SupportedPresets);
v6AddedTrace.configurePresets[0].trace = {};
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify(v6AddedTrace));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(2);
expect(presetsFileErrors.filter((e) => e.includes("should NOT have additional properties: trace"))).to.have.lengthOf(1);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(0);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(0);
expect(preset.testPresets(sourceDirectory).length).to.be.equal(0);
expect(preset.packagePresets(sourceDirectory).length).to.be.equal(0);
expect(preset.workflowPresets(sourceDirectory).length).to.be.equal(0);
}).timeout(100000);
const version7SupportedPresets: any = {
"version": 7,
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolchainFile": "",
"trace": {}
}
],
"buildPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"cleanFirst": true,
"resolvePackageReferences": "on"
}
],
"testPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"output": {
"testOutputTruncation": "tail"
}
}
],
"packagePresets": [
{
"name": "x64-debug-package"
}
],
"workflowPresets": [
{
"name": "x64-debug-workflow",
"steps": [
{
"type": "configure",
"name": "configure"
}
]
}
]
};
/**
* First validate the version 7 supports the `trace` field.
* Then, confirm that the `$schema` field isn't allowed in v7.
*/
test('Validate version 7 CMake Presets', async () => {
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify(version7SupportedPresets));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(0);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(1);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(1);
expect(preset.testPresets(sourceDirectory).length).to.be.equal(1);
expect(preset.packagePresets(sourceDirectory).length).to.be.equal(1);
expect(preset.workflowPresets(sourceDirectory).length).to.be.equal(1);
const v7AddedSchema = lodash.cloneDeep(version7SupportedPresets);
v7AddedSchema["$schema"] = "test";
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify(v7AddedSchema));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(2);
expect(presetsFileErrors.filter((e) => e.includes("should NOT have additional properties: $schema"))).to.have.lengthOf(1);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(0);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(0);
expect(preset.testPresets(sourceDirectory).length).to.be.equal(0);
expect(preset.packagePresets(sourceDirectory).length).to.be.equal(0);
expect(preset.workflowPresets(sourceDirectory).length).to.be.equal(0);
}).timeout(100000);
/**
* Confirm that penv expansion doesn't work for `include` in v6.
* Then, confirm that penv works in v7.
*/
test('Validate `include` field supporting penv macro expansion in v7', async () => {
const v6WithInclude: any = lodash.cloneDeep(v6SupportedPresets);
v6WithInclude.include = ["$penv{TEST}/test.json"];
fs.writeFileSync(presetsParser.presetsPath, JSON.stringify(v6WithInclude));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(1);
expect(presetsFileErrors.filter((e) => e.includes("penv") && e.includes("cannot be found"))).to.have.lengthOf(1);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(0);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(0);
expect(preset.testPresets(sourceDirectory).length).to.be.equal(0);
expect(preset.packagePresets(sourceDirectory).length).to.be.equal(0);
expect(preset.workflowPresets(sourceDirectory).length).to.be.equal(0);
presetsFileErrors = [];
process.env.TEST = sourceDirectory;
const v7WithInclude: any = lodash.cloneDeep(version7SupportedPresets);
v7WithInclude.include = ["$penv{TEST}/test.json"];
// We need a unique name in order to confirm that the presets get included.
v7WithInclude.configurePresets[0].name = "testName";
fs.writeFileSync(presetsParser.presetsPath, JSON.stringify(v7WithInclude));
// Create the include file.
fs.writeFileSync(path.join(presetsParser.presetsPath, "..", "test.json"),
JSON.stringify(v3SupportedPresets));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(0);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(2);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(1);
expect(preset.testPresets(sourceDirectory).length).to.be.equal(1);
expect(preset.packagePresets(sourceDirectory).length).to.be.equal(1);
expect(preset.workflowPresets(sourceDirectory).length).to.be.equal(1);
// Remove the include file.
fs.rmSync(path.join(presetsParser.presetsPath, "..", "test.json"));
}).timeout(100000);
/**
* Validate the v8 supports `$schema` field.
*/
test('Validate version 8 CMake Presets', async () => {
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify({
"version": 8,
"$schema": "test",
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolchainFile": "",
"trace": {}
}
],
"buildPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"cleanFirst": true,
"resolvePackageReferences": "on"
}
],
"testPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"output": {
"testOutputTruncation": "tail"
}
}
],
"packagePresets": [
{
"name": "x64-debug-package"
}
],
"workflowPresets": [
{
"name": "x64-debug-workflow",
"steps": [
{
"type": "configure",
"name": "configure"
}
]
}
]
}
));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(0);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(1);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(1);
expect(preset.testPresets(sourceDirectory).length).to.be.equal(1);
expect(preset.packagePresets(sourceDirectory).length).to.be.equal(1);
expect(preset.workflowPresets(sourceDirectory).length).to.be.equal(1);
});
/**
* Validate that CMake Presets v9 is supported, specifically additional macros in the `include` field.
*/
test('Validate version 9 CMake Presets', async () => {
const v9WithInclude: any = lodash.cloneDeep(v6SupportedPresets);
v9WithInclude.version = 9;
v9WithInclude.include = ["${sourceDir}/test.json"];
// We need a unique configure preset name.
v9WithInclude.configurePresets[0].name = "testName";
fs.writeFileSync(presetsParser.presetsPath, JSON.stringify(v9WithInclude));
fs.writeFileSync(path.join(presetsParser.presetsPath, "..", "test.json"), JSON.stringify(v3SupportedPresets));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(0);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(2);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(1);
expect(preset.testPresets(sourceDirectory).length).to.be.equal(1);
expect(preset.packagePresets(sourceDirectory).length).to.be.equal(1);
expect(preset.workflowPresets(sourceDirectory).length).to.be.equal(1);
}).timeout(100000);
});
suite('Presets include field and CMakePresets+CMakeUserPresets', () => {
const presets: any = {
"version": 9,
"configurePresets": [
{
"name": "presetConfigurePreset",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"toolchainFile": ""
}
]
};
const userPreset: any = {
"version": 9,
"configurePresets": [
{
"name": "userPresetConfigurePreset",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"toolchainFile": ""
}
]
};
const includedPreset: any = {
"version": 9,
"configurePresets": [
{
"name": "includedConfigurePreset",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"toolchainFile": ""
}
]
};
test('Ensure CMakeUserPresets inherently includes CMakePresets', async () => {
fs.writeFileSync(presetsParser.presetsPath, JSON.stringify(presets));
fs.writeFileSync(presetsParser.userPresetsPath, JSON.stringify(userPreset));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(0);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(1);
expect(preset.userConfigurePresets(sourceDirectory).length).to.be.equal(2);
});
test('Ensure included field works combined with user preset', async () => {
const updatedPresets = lodash.cloneDeep(presets);
updatedPresets.include = ["./included.json"];
fs.writeFileSync(presetsParser.presetsPath, JSON.stringify(updatedPresets));
fs.writeFileSync(presetsParser.userPresetsPath, JSON.stringify(userPreset));
fs.writeFileSync(path.join(presetsParser.presetsPath, "..", "included.json"), JSON.stringify(includedPreset));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(0);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(2);
expect(preset.userConfigurePresets(sourceDirectory).length).to.be.equal(3);
});
});
suite('Presets inheritance and expansions', () => {
test('Testing inheritance of cacheVariables - 3603', async () => {
const asset = fs.readFileSync(path.join(__dirname, "..", "..", "..", "..", "test", "integration-tests", "presets", "assets", "3603_CMakePresets.json"), "utf-8");
fs.writeFileSync(presetsParser.presetsPath, asset);
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(0);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(4);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(12);
const toolsMSVCConfigPreset = preset.configurePresets(sourceDirectory).find(p => p.name === "tools-MSVC");
expect(toolsMSVCConfigPreset?.cacheVariables?.["BUILD_TOOLS"]).to.be.equal(true);
expect(toolsMSVCConfigPreset?.cacheVariables?.["CMAKE_C_COMPILER"]).to.be.equal("cl");
expect(toolsMSVCConfigPreset?.cacheVariables?.["CMAKE_CXX_COMPILER"]).to.be.equal("cl");
expect(toolsMSVCConfigPreset?.cacheVariables?.["CMAKE_EXPORT_COMPILE_COMMANDS"]).to.be.equal(true);
});
test('Testing inheritance and expansion of PATH - 3473', async () => {
const asset = fs.readFileSync(path.join(__dirname, "..", "..", "..", "..", "test", "integration-tests", "presets", "assets", "3473_CMakePresets.json"), "utf-8");
fs.writeFileSync(presetsParser.presetsPath, asset);
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(0);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(3);
const customConfigurePreset = preset.configurePresets(sourceDirectory).find(p => p.name === "custom");
expect(customConfigurePreset?.environment?.PATH?.startsWith("C:\\msys64\\ucrt64\\bin;")).to.be.equal(true);
if (process.platform === "win32") {
expect(customConfigurePreset?.environment?.PATH?.includes("Program Files")).to.be.equal(true);
} else {
expect(customConfigurePreset?.environment?.PATH?.includes("$penv{PATH}")).to.be.equal(false);
}
});
test('Testing inheritance and overriding of variables', async () => {
fs.writeFileSync(presetsParser.presetsPath, JSON.stringify({
"version": 3,
"configurePresets": [
{
"name": "default",
"environment": {
"PATH": "C:\\msys64\\ucrt64\\bin;$penv{PATH}",
"TEST": "test"
}
},
{
"name": "custom",
"inherits": ["default"],
"environment": {
"UPDATE_PATH": "$env{PATH}",
"TEST": "overridden"
}
}
]
}));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(0);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(2);
const configurePreset = preset.configurePresets(sourceDirectory).find(p => p.name === "custom");
expect(configurePreset?.environment?.UPDATE_PATH?.startsWith("C:/msys64/ucrt64/bin;")).to.be.equal(true);
expect(configurePreset?.environment?.TEST).to.be.equal("overridden");
});
});
teardown(async () => {
if (fs.existsSync(presetsParser.presetsPath)) {
fs.rmSync(presetsParser.presetsPath);
}
if (fs.existsSync(presetsParser.userPresetsPath)) {
fs.rmSync(presetsParser.userPresetsPath);
}
});
});

Просмотреть файл

@ -0,0 +1,36 @@
import * as path from 'path';
import { runTests } from '@vscode/test-electron';
async function main() {
try {
// The folder containing the Extension Manifest package.json
// Passed to `--extensionDevelopmentPath`
const extensionDevelopmentPath = path.resolve(__dirname, '../../../');
// The path to the extension test runner script
// Passed to --extensionTestsPath
const extensionTestsPath = path.resolve(__dirname, './index');
// The current folder is the default workspace.
// The driver tests change the default workspace folder.
const testWorkspace = path.resolve(extensionDevelopmentPath, 'test/integration-tests');
const launchArgs = ["--disable-extensions", "--disable-workspace-trust", testWorkspace];
const extensionTestsEnv: { [key: string]: string | undefined } = {
"CMT_TESTING": "1",
"CMT_QUIET_CONSOLE": "1",
"TEST_FILTER": process.env.TEST_FILTER ?? ".*"
};
// Download VS Code, unzip it and run the integration test
await runTests({ launchArgs, extensionDevelopmentPath, extensionTestsPath, extensionTestsEnv });
} catch (err) {
console.error(err);
console.error('Failed to run tests');
process.exit(1);
}
}
void main();

Просмотреть файл

@ -1,834 +0,0 @@
import { ExpansionErrorHandler } from "@cmt/expand";
import { PresetsFile } from "@cmt/presets/preset";
import { PresetsParser } from "@cmt/presets/presetsParser";
import { expect } from "@test/util";
import * as fs from "fs";
import * as preset from "@cmt/presets/preset";
import * as path from "path";
import * as lodash from "lodash";
/**
* This test suite is designed specifically for testing the validation of a CMake Presets file.
* This specifically means that we are testing the existence of fields in the presets file based on what is supported for each
* presets version.
* TODO: It might be more clear to break this up into multiple test suites. This could be a suite per version of Presets, or a suite per validation/inclusion/expansion, etc.
* In order to do this, it might be beneficial to create a helper class so we don't duplicate the setup code.
* TODO: It might be wise to consider having actual these tests based on a file that is in the repo, not just created on the fly as
* this could make it easier for integration tests and/or e2e tests.
*/
suite('Presets validation, inclusion, and expansion tests', () => {
let workspaceFolder: string;
let sourceDirectory: string;
let folderPath: string;
let presetsFileVersionErrors: string[] = [];
let presetsFileErrors: string[] = [];
let presetsParser: PresetsParser;
suiteSetup(async function(this: Mocha.Context) {
this.timeout(100000);
workspaceFolder = __dirname;
sourceDirectory = workspaceFolder;
folderPath = sourceDirectory;
presetsParser = new PresetsParser(
folderPath,
sourceDirectory,
workspaceFolder,
async (_path: string, _errors: ExpansionErrorHandler) => {
_errors.errorList.forEach((error) => {
presetsFileErrors.push(error[0]);
});
},
async (_file: string) => {
presetsFileVersionErrors.push(`Version error in ${_file}`);
},
(_filePath: string) => {
console.log("Modifying the collection for the Problems pane, not needed in this unit test");
},
(_file: PresetsFile | undefined) => {
console.log("Presets file handler");
},
(_file: PresetsFile | undefined) => {
console.log("User Presets file handler");
}
);
});
setup(async function(this: Mocha.Context) {
this.timeout(100000);
presetsFileVersionErrors = [];
presetsFileErrors = [];
});
test('Validate that we fail on CMakePresets version 1', async () => {
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify({
"version": 1,
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja",
"binaryDir": "${workspaceFolder}/build"
}
]
}
));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileVersionErrors).to.have.lengthOf(1);
}).timeout(100000);
/**
* TODO: We need improvements in the code to ensure that we're requiring `binaryDir` in version 2.
* Test version 2 of CMake Prests.
* We want to ensure that we're requiring `binaryDir`.
* `installDir`, `condition`, `toolchainFile` are not supported in version 2.
*/
/* test('Validate version 2 CMakePresets, requires binaryDir', async () => {
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify({
"version": 2,
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja"
}
]
}
));
await presetsParser.resetPresetsFiles(
(_f, p) => (presetsContainer.expandedPresets = p),
(_f, p) => (presetsContainer.expandedUserPresets = p),
(_f, p) => (presetsContainer.presetsPlusIncluded = p),
(_f, p) => (presetsContainer.userPresetsPlusIncluded = p),
(_f, p) => (presetsContainer.originalPresets = p),
(_f, p) => (presetsContainer.originalUserPresets = p),
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(1);
expect(presetsFileErrors.filter((e) => e.includes("binaryDir"))).to.have.lengthOf(1);
expect(presetsContainer.expandedPresets).to.be.undefined;
expect(presetsContainer.expandedUserPresets).to.be.undefined;
expect(presetsContainer.presetsPlusIncluded).to.be.undefined;
expect(presetsContainer.userPresetsPlusIncluded).to.be.undefined;
}).timeout(100000);*/
/**
* Test version 2 of CMake Prests.
* Ensure that we're validating and that `installDir`, `condition`, and `toolchainFile` aren't allowed.
*/
test('Validate version 2 CMakePresets, requires binaryDir', async () => {
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify({
"version": 2,
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolchainFile": ""
}
]
}
));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(4);
expect(presetsFileErrors.filter((e) => e.includes("should NOT have additional properties: installDir"))).to.have.lengthOf(1);
expect(presetsFileErrors.filter((e) => e.includes("should NOT have additional properties: condition"))).to.have.lengthOf(1);
expect(presetsFileErrors.filter((e) => e.includes("should NOT have additional properties: toolchainFile"))).to.have.lengthOf(1);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(0);
}).timeout(100000);
const v3SupportedPresets: any = {
"version": 3,
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolchainFile": ""
}
]
};
/**
* Test validation of version 3 of CMake Prests.
* Ensure that `installDir` and `condition` are accepted.
*
* Then, add add `include` and `buildPresets with `resolvePackageReference`, confirm that `include` and `resolvePackageReference` are not allowed.
*/
test('Validate version 3 CMakePresets', async () => {
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify(v3SupportedPresets));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(0);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(1);
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify({
"version": 3,
"include": ["test.json"],
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolchainFile": ""
}
],
"buildPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"cleanFirst": true,
"resolvePackageReferences": "on"
}
]
}
));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(3);
expect(presetsFileErrors.filter((e) => e.includes("should NOT have additional properties: include"))).to.have.lengthOf(1);
expect(presetsFileErrors.filter((e) => e.includes("should NOT have additional properties: resolvePackageReference"))).to.have.lengthOf(1);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(0);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(0);
}).timeout(100000);
/**
* First test that the `include` and `resolvePackageReferences` fields are allowed in version 4.
* Then, test that fields only allowed in 5 aren't supported, by adding a testPreset with the `testOutputTrunction` field added.
*/
test('Validate version 4 CMakePresets', async () => {
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify({
"version": 4,
"include": ["test.json"],
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolchainFile": ""
}
],
"buildPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"cleanFirst": true,
"resolvePackageReferences": "on"
}
]
}
));
fs.writeFileSync(path.join(presetsParser.presetsPath, "..", "test.json"),
JSON.stringify({
"version": 4,
"configurePresets": [
{
"name": "blah",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolchainFile": ""
}
]
}
));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(0);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(2);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(1);
// Remove the include.
fs.rmSync(path.join(presetsParser.presetsPath, "..", "test.json"));
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify({
"version": 4,
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolchainFile": ""
}
],
"buildPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"cleanFirst": true,
"resolvePackageReferences": "on"
}
],
"testPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"output": {
"testOutputTruncation": "tail"
}
}
]
}
));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(2);
expect(presetsFileErrors.filter((e) => e.includes("should NOT have additional properties: testOutputTruncation"))).to.have.lengthOf(1);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(0);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(0);
}).timeout(100000);
/**
* First test that the `testOutputTruncation field is allowed in version 5.
*/
test('Validate version 5 CMakePresets', async () => {
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify({
"version": 5,
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolchainFile": ""
}
],
"buildPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"cleanFirst": true,
"resolvePackageReferences": "on"
}
],
"testPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"output": {
"testOutputTruncation": "tail"
}
}
]
}
));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(0);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(1);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(1);
expect(preset.testPresets(sourceDirectory).length).to.be.equal(1);
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify({
"version": 5,
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolchainFile": ""
}
],
"buildPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"cleanFirst": true,
"resolvePackageReferences": "on"
}
],
"testPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"output": {
"testOutputTruncation": "tail"
}
}
],
"packagePresets": [
{
"name": "x64-debug-package"
}
],
"workflowPresets": [
{
"name": "x64-debug-workflow",
"steps": [
{
"type": "configure",
"name": "x64-debug"
}
]
}
]
}
));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(3);
expect(presetsFileErrors.filter((e) => e.includes("should NOT have additional properties: packagePresets"))).to.have.lengthOf(1);
expect(presetsFileErrors.filter((e) => e.includes("should NOT have additional properties: workflowPresets"))).to.have.lengthOf(1);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(0);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(0);
expect(preset.testPresets(sourceDirectory).length).to.be.equal(0);
expect(preset.packagePresets(sourceDirectory).length).to.be.equal(0);
expect(preset.workflowPresets(sourceDirectory).length).to.be.equal(0);
}).timeout(100000);
const v6SupportedPresets: any = {
"version": 6,
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolchainFile": ""
}
],
"buildPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"cleanFirst": true,
"resolvePackageReferences": "on"
}
],
"testPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"output": {
"testOutputTruncation": "tail"
}
}
],
"packagePresets": [
{
"name": "x64-debug-package"
}
],
"workflowPresets": [
{
"name": "x64-debug-workflow",
"steps": [
{
"type": "configure",
"name": "configure"
}
]
}
]
};
/**
* Validate the `packagePresets` and `workflowPresets` are supported in Presets v6.
* Then, confirm that the `trace` object isn't allowed in v6, as it was introduced in v7
*/
test('Validate version 6 CMakePresets', async () => {
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify(v6SupportedPresets));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(0);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(1);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(1);
expect(preset.testPresets(sourceDirectory).length).to.be.equal(1);
expect(preset.packagePresets(sourceDirectory).length).to.be.equal(1);
expect(preset.workflowPresets(sourceDirectory).length).to.be.equal(1);
const v6AddedTrace = lodash.cloneDeep(v6SupportedPresets);
v6AddedTrace.configurePresets[0].trace = {};
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify(v6AddedTrace));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(2);
expect(presetsFileErrors.filter((e) => e.includes("should NOT have additional properties: trace"))).to.have.lengthOf(1);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(0);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(0);
expect(preset.testPresets(sourceDirectory).length).to.be.equal(0);
expect(preset.packagePresets(sourceDirectory).length).to.be.equal(0);
expect(preset.workflowPresets(sourceDirectory).length).to.be.equal(0);
}).timeout(100000);
const version7SupportedPresets: any = {
"version": 7,
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolchainFile": "",
"trace": {}
}
],
"buildPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"cleanFirst": true,
"resolvePackageReferences": "on"
}
],
"testPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"output": {
"testOutputTruncation": "tail"
}
}
],
"packagePresets": [
{
"name": "x64-debug-package"
}
],
"workflowPresets": [
{
"name": "x64-debug-workflow",
"steps": [
{
"type": "configure",
"name": "configure"
}
]
}
]
};
/**
* First validate the version 7 supports the `trace` field.
* Then, confirm that the `$schema` field isn't allowed in v7.
*/
test('Validate version 7 CMake Presets', async () => {
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify(version7SupportedPresets));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(0);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(1);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(1);
expect(preset.testPresets(sourceDirectory).length).to.be.equal(1);
expect(preset.packagePresets(sourceDirectory).length).to.be.equal(1);
expect(preset.workflowPresets(sourceDirectory).length).to.be.equal(1);
const v7AddedSchema = lodash.cloneDeep(version7SupportedPresets);
v7AddedSchema["$schema"] = "test";
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify(v7AddedSchema));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(2);
expect(presetsFileErrors.filter((e) => e.includes("should NOT have additional properties: $schema"))).to.have.lengthOf(1);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(0);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(0);
expect(preset.testPresets(sourceDirectory).length).to.be.equal(0);
expect(preset.packagePresets(sourceDirectory).length).to.be.equal(0);
expect(preset.workflowPresets(sourceDirectory).length).to.be.equal(0);
}).timeout(100000);
/**
* Confirm that penv expansion doesn't work for `include` in v6.
* Then, confirm that penv works in v7.
*/
test('Validate `include` field supporting penv macro expansion in v7', async () => {
const v6WithInclude: any = lodash.cloneDeep(v6SupportedPresets);
v6WithInclude.include = ["$penv{TEST}/test.json"];
fs.writeFileSync(presetsParser.presetsPath, JSON.stringify(v6WithInclude));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(1);
expect(presetsFileErrors.filter((e) => e.includes("penv") && e.includes("cannot be found"))).to.have.lengthOf(1);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(0);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(0);
expect(preset.testPresets(sourceDirectory).length).to.be.equal(0);
expect(preset.packagePresets(sourceDirectory).length).to.be.equal(0);
expect(preset.workflowPresets(sourceDirectory).length).to.be.equal(0);
presetsFileErrors = [];
process.env.TEST = sourceDirectory;
const v7WithInclude: any = lodash.cloneDeep(version7SupportedPresets);
v7WithInclude.include = ["$penv{TEST}/test.json"];
// We need a unique name in order to confirm that the presets get included.
v7WithInclude.configurePresets[0].name = "testName";
fs.writeFileSync(presetsParser.presetsPath, JSON.stringify(v7WithInclude));
// Create the include file.
fs.writeFileSync(path.join(presetsParser.presetsPath, "..", "test.json"),
JSON.stringify(v3SupportedPresets));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(0);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(2);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(1);
expect(preset.testPresets(sourceDirectory).length).to.be.equal(1);
expect(preset.packagePresets(sourceDirectory).length).to.be.equal(1);
expect(preset.workflowPresets(sourceDirectory).length).to.be.equal(1);
// Remove the include file.
fs.rmSync(path.join(presetsParser.presetsPath, "..", "test.json"));
}).timeout(100000);
/**
* Validate the v8 supports `$schema` field.
*/
test('Validate version 8 CMake Presets', async () => {
fs.writeFileSync(presetsParser.presetsPath,
JSON.stringify({
"version": 8,
"$schema": "test",
"configurePresets": [
{
"name": "configure",
"hidden": false,
"generator": "Ninja",
"installDir": "${workspaceFolder}/install",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"toolchainFile": "",
"trace": {}
}
],
"buildPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"cleanFirst": true,
"resolvePackageReferences": "on"
}
],
"testPresets": [
{
"name": "x64-debug",
"configurePreset": "configure",
"output": {
"testOutputTruncation": "tail"
}
}
],
"packagePresets": [
{
"name": "x64-debug-package"
}
],
"workflowPresets": [
{
"name": "x64-debug-workflow",
"steps": [
{
"type": "configure",
"name": "configure"
}
]
}
]
}
));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(0);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(1);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(1);
expect(preset.testPresets(sourceDirectory).length).to.be.equal(1);
expect(preset.packagePresets(sourceDirectory).length).to.be.equal(1);
expect(preset.workflowPresets(sourceDirectory).length).to.be.equal(1);
});
/**
* Validate that CMake Presets v9 is supported, specifically additional macros in the `include` field.
*/
test('Validate version 9 CMake Presets', async () => {
const v9WithInclude: any = lodash.cloneDeep(v6SupportedPresets);
v9WithInclude.version = 9;
v9WithInclude.include = ["${sourceDir}/test.json"];
// We need a unique configure preset name.
v9WithInclude.configurePresets[0].name = "testName";
fs.writeFileSync(presetsParser.presetsPath, JSON.stringify(v9WithInclude));
fs.writeFileSync(path.join(presetsParser.presetsPath, "..", "test.json"), JSON.stringify(v3SupportedPresets));
await presetsParser.resetPresetsFiles(
new Map<string, PresetsFile>(),
false,
false
);
expect(presetsFileErrors).to.have.lengthOf(0);
expect(preset.configurePresets(sourceDirectory).length).to.be.equal(2);
expect(preset.buildPresets(sourceDirectory).length).to.be.equal(1);
expect(preset.testPresets(sourceDirectory).length).to.be.equal(1);
expect(preset.packagePresets(sourceDirectory).length).to.be.equal(1);
expect(preset.workflowPresets(sourceDirectory).length).to.be.equal(1);
}).timeout(100000);
teardown(async () => {
if (fs.existsSync(presetsParser.presetsPath)) {
fs.rmSync(presetsParser.presetsPath);
}
if (fs.existsSync(presetsParser.userPresetsPath)) {
fs.rmSync(presetsParser.userPresetsPath);
}
});
});