Skip to content
This repository has been archived by the owner on Oct 20, 2024. It is now read-only.

chore: use vitest #480

Closed
wants to merge 14 commits into from
Prev Previous commit
Next Next commit
feat: add integration testing against snapshots
  • Loading branch information
manuel3108 committed Jul 28, 2024
commit 500bcd7f35373fe844087a21390e6c35c130694d
17 changes: 15 additions & 2 deletions packages/core/adder/execute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,18 @@ export type AddersExecutionPlan = {
selectAddersToApply?: AddersToApplySelector;
};

export type AddersExecutionResult = {
success: boolean;
outputDirectory: string;
changedFiles?: Set<string>;
};

export async function executeAdder<Args extends OptionDefinition>(
adderDetails: AdderDetails<Args>,
executingAdderInfo: ExecutingAdderInfo,
remoteControlOptions: RemoteControlOptions | undefined = undefined,
) {
await executeAdders([adderDetails], executingAdderInfo, remoteControlOptions);
return await executeAdders([adderDetails], executingAdderInfo, remoteControlOptions);
}

export async function executeAdders<Args extends OptionDefinition>(
Expand Down Expand Up @@ -104,7 +110,7 @@ export async function executeAdders<Args extends OptionDefinition>(
selectAddersToApply,
};

await executePlan(executionPlan, executingAdder, adderDetails, remoteControlOptions);
return await executePlan(executionPlan, executingAdder, adderDetails, remoteControlOptions);
} catch (e) {
if (e instanceof Error) cancel(e.message);
else cancel('Something went wrong.');
Expand Down Expand Up @@ -273,6 +279,13 @@ async function executePlan<Args extends OptionDefinition>(
displayNextSteps(adderDetails, isApplyingMultipleAdders, executionPlan);
endPrompts("You're all set!");
}

const executionResult: AddersExecutionResult = {
success: true,
changedFiles: filesToFormat,
outputDirectory: executionPlan.workingDirectory,
};
return executionResult;
}

async function processInlineAdder<Args extends OptionDefinition>(
Expand Down
8 changes: 6 additions & 2 deletions packages/testing-library/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { generateTestCases, runAdderTests } from './utils/test-cases';
import {
generateTestCases,
runAdderEndToEndTests,
runAdderIntegrationTests,
} from './utils/test-cases';
import { prepareTests } from './utils/workspace';

export type TestOptions = {
Expand All @@ -7,4 +11,4 @@ export type TestOptions = {
outputDirectory: string;
};

export { generateTestCases, runAdderTests, prepareTests };
export { generateTestCases, runAdderEndToEndTests, runAdderIntegrationTests, prepareTests };
10 changes: 9 additions & 1 deletion packages/testing-library/utils/adder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,19 @@ export async function runAdder(
adderOptions,
};

await executeAdder(
return await executeAdder(
{ config: adder.config, checks: adder.checks },
{ name: '@svelte-add/testing-library', version: 'latest' },
remoteControlOptions,
);
}

export async function runAdderAndPrepareTests(
adder: AdderWithoutExplicitArgs,
workingDirectory: string,
optionValues: OptionValues<Record<string, Question>>,
) {
await runAdder(adder, workingDirectory, optionValues);

const workspace = createEmptyWorkspace();
workspace.cwd = workingDirectory;
Expand Down
61 changes: 46 additions & 15 deletions packages/testing-library/utils/test-cases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export function generateTestCases(adders: AdderWithoutExplicitArgs[]) {
return testCases;
}

export async function runAdderTests(
export async function runAdderEndToEndTests(
template: string,
adder: AdderWithoutExplicitArgs,
options: OptionValues<Record<string, Question>>,
Expand All @@ -69,24 +69,13 @@ export async function runAdderTests(

remoteControl.enable();

// generate a unique descriptive folder name if options are present
const optionsString = Object.entries(options)
.filter((data) => data[1]) // ensure value it not undefined
.map(([key, value]) => `${key}=${value as string}`)
.join('+');

const output = join(
testOptions.outputDirectory,
adder.config.metadata.id,
template,
optionsString,
);
const output = generateOutputDirectory(options, testOptions.outputDirectory, adder, template);
await mkdir(output, { recursive: true });

const workingDirectory = await prepareWorkspaceWithTemplate(
output,
template,
getTemplatesDirectory(testOptions),
getTemplatesDirectory(testOptions.outputDirectory),
);

await runAdder(adder, workingDirectory, options);
Expand All @@ -113,12 +102,49 @@ export async function runAdderTests(
}
}

export async function runAdderIntegrationTests(
testCase: TestCase,
outputDirectory: string,
adder: AdderWithoutExplicitArgs,
) {
const adderOutputDirectory = generateOutputDirectory(
testCase.options,
outputDirectory,
adder,
testCase.template,
);

const workingDirectory = await prepareWorkspaceWithTemplate(
adderOutputDirectory,
testCase.template,
getTemplatesDirectory(outputDirectory),
);

return await runAdder(adder, workingDirectory, testCase.options);
}

export type AdderError = {
adder: string;
template: string;
message: string;
} & Error;

export function generateOutputDirectory(
options: OptionValues<Record<string, Question>>,
outputDirectory: string,
adder: AdderWithoutExplicitArgs,
template: string,
) {
// generate a unique descriptive folder name if options are present
const optionsString = Object.entries(options)
.filter((data) => data[1]) // ensure value it not undefined
.map(([key, value]) => `${key}=${value as string}`)
.join('+');

const output = join(outputDirectory, adder.config.metadata.id, template, optionsString);
return output;
}

export async function runTestCases(testCases: Map<string, TestCase[]>, testOptions: TestOptions) {
const asyncTasks: Array<() => Promise<void>> = [];
const syncTasks: Array<() => Promise<void>> = [];
Expand All @@ -128,7 +154,12 @@ export async function runTestCases(testCases: Map<string, TestCase[]>, testOptio
for (const testCase of values) {
const taskExecutor = async () => {
try {
await runAdderTests(testCase.template, testCase.adder, testCase.options, testOptions);
await runAdderEndToEndTests(
testCase.template,
testCase.adder,
testCase.options,
testOptions,
);
} catch (e) {
const error = e as Error;
const adderError: AdderError = {
Expand Down
11 changes: 5 additions & 6 deletions packages/testing-library/utils/workspace.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { join } from 'node:path';
import { cp, mkdir, rm } from 'node:fs/promises';
import { executeCli } from '@svelte-add/core';
import type { TestOptions } from '..';
import { downloadProjectTemplates } from './create-project';

const templatesDirectory = 'templates';

export function getTemplatesDirectory(options: TestOptions) {
return join(options.outputDirectory, templatesDirectory);
export function getTemplatesDirectory(outputDirectory: string) {
return join(outputDirectory, templatesDirectory);
}

export async function installDependencies(output: string) {
Expand All @@ -33,11 +32,11 @@ export async function prepareWorkspaceWithTemplate(
return output;
}

export async function prepareTests(options: TestOptions) {
export async function prepareTests(outputDirectory: string) {
console.log('deleting old files');
await rm(options.outputDirectory, { recursive: true, force: true });
await rm(outputDirectory, { recursive: true, force: true });

console.log('downloading project templates');
const templatesOutputDirectory = getTemplatesDirectory(options);
const templatesOutputDirectory = getTemplatesDirectory(outputDirectory);
await downloadProjectTemplates(templatesOutputDirectory);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "test",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch"
},
"devDependencies": {
"@popperjs/core": "^2.11.8",
"@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"bootstrap": "^5.3.3",
"svelte": "^4.2.7",
"svelte-check": "^3.6.0",
"typescript": "^5.0.0",
"vite": "^5.0.3"
},
"type": "module"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<script>import { browser } from "$app/environment";
import { onMount } from "svelte";
import "bootstrap/dist/css/bootstrap.css";

onMount(async () => {
if (!browser) return;

// this is enough for most components
await import("bootstrap");

// some components require a bootstrap instance, to fulfil their job. In that case, use this:
// const bootstrap = await import("bootstrap");
// sample usage:
// const toastBootstrap = bootstrap.Toast.getOrCreateInstance(toastLiveExample)
});</script><slot></slot>
<slot></slot>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "test",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch"
},
"devDependencies": {
"@popperjs/core": "^2.11.8",
"@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"bootstrap": "^5.3.3",
"sass": "^1.77.5",
"svelte": "^4.2.7",
"svelte-check": "^3.6.0",
"typescript": "^5.0.0",
"vite": "^5.0.3"
},
"type": "module"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* 1. Include functions first (so you can manipulate colors, SVGs, calc, etc) */
@import "bootstrap/scss/functions";
/* 2. Include any default variable overrides here */
$body-bg: $background;
/* 3. Include remainder of required Bootstrap stylesheets (including any separate color mode stylesheets) */
@import "bootstrap/scss/variables";
@import "bootstrap/scss/variables-dark";
/* 4. Include any default map overrides here */
/* 5. Include remainder of required parts */
@import "bootstrap/scss/maps";
@import "bootstrap/scss/mixins";
@import "bootstrap/scss/root";
/* 6. Optionally include any other parts as needed */
@import "bootstrap/scss/utilities";
@import "bootstrap/scss/reboot";
@import "bootstrap/scss/type";
@import "bootstrap/scss/helpers";
@import "bootstrap/scss/buttons";
/* 7. Optionally include utilities API last to generate classes based on the Sass map in `_utilities.scss` */
@import "bootstrap/scss/utilities/api";
/* Add additional custom code here */
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<script>import { browser } from "$app/environment";
import { onMount } from "svelte";
import "../app.scss";

onMount(async () => {
if (!browser) return;

// this is enough for most components
await import("bootstrap");

// some components require a bootstrap instance, to fulfil their job. In that case, use this:
// const bootstrap = await import("bootstrap");
// sample usage:
// const toastBootstrap = bootstrap.Toast.getOrCreateInstance(toastLiveExample)
});</script><slot></slot>
<slot></slot>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/* Set your brand colors */
$background: lightgrey;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default defineConfig({
css: {
preprocessorOptions: {
scss: {
additionalData: "@use \"src/variables.scss\" as *;"
}
}
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "test",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview"
},
"devDependencies": {
"@popperjs/core": "^2.11.8",
"@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"bootstrap": "^5.3.3",
"svelte": "^4.2.7",
"vite": "^5.0.3"
},
"type": "module"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<script>import { browser } from "$app/environment";
import { onMount } from "svelte";
import "bootstrap/dist/css/bootstrap.css";

onMount(async () => {
if (!browser) return;

// this is enough for most components
await import("bootstrap");

// some components require a bootstrap instance, to fulfil their job. In that case, use this:
// const bootstrap = await import("bootstrap");
// sample usage:
// const toastBootstrap = bootstrap.Toast.getOrCreateInstance(toastLiveExample)
});</script><slot></slot>
<slot></slot>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "test",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview"
},
"devDependencies": {
"@popperjs/core": "^2.11.8",
"@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"bootstrap": "^5.3.3",
"sass": "^1.77.5",
"svelte": "^4.2.7",
"vite": "^5.0.3"
},
"type": "module"
}
Loading
Loading