ファイルの読み書きを伴うモジュールのDeno.test
25649 ワード
下記の様なts-morphを使用したoverloadを追加する関数のテストを用意してみます。
import { FunctionDeclaration } from "https://deno.land/x/[email protected]/mod.ts";
type Parameter = { name: string; type: string };
type Entry = { parameters: Parameter[] };
export const addCustomEntries = (
entries: Entry[],
constructor: FunctionDeclaration
) => {
constructor.addOverloads(
entries.map((entry) => ({
parameters: entry.parameters,
returnType: "string",
}))
);
};
helperの定義
ファイルの読み書きを行うために前後処理を実行するヘルパー関数を定義します。
helper.ts
import {
Project,
SourceFile,
ManipulationSettings,
IndentationText,
} from "https://deno.land/x/[email protected]/mod.ts";
export const withDir = async (
cb: (tempDir: string) => void | Promise<void>
) => {
const tempDir = await Deno.makeTempDir({
prefix: "deno_couscous_test_",
});
await cb(tempDir);
await Deno.remove(tempDir, { recursive: true });
};
export const withSource = (
cb: (tempSrc: SourceFile) => void | Promise<void>,
manipulationSettings: Partial<ManipulationSettings> = {
indentationText: IndentationText.TwoSpaces,
}
) =>
withDir(async (tempDir) => {
const tempFile = await Deno.makeTempFile({ dir: tempDir });
const project = new Project({
libFolderPath: tempDir,
manipulationSettings,
});
const source = project.addSourceFileAtPath(tempFile);
await cb(source);
});
加えてfile同士を比較するアサーションの定義もしておきます。
assertEqualFiles.ts
import { assertEquals } from "https://deno.land/[email protected]/testing/asserts.ts";
export const assertEqualFile = async (
receivedPath: string,
expectedPath: string
) => {
const [received, expected] = await Promise.all([
Deno.readTextFile(receivedPath),
Deno.readTextFile(expectedPath),
]);
await assertEquals(received, expected);
};
テストケースの実装
今回はスナップショットテストの出力結果をハードコーディングしていますが、実装の仕方によっては自動生成も可能だと思います。
output.ts.snapshot
function hoge(piyo: string): string;
function hoge(piyo: string, foo: number): string;
function hoge(foo: number, bar: boolean): string;
function hoge(piyo: string, foo: number, bar: number): string;
function hoge() {
return ""
}
あくまでoverloadの検査であって、関数自体の検査は含まれていないので最低限の実装をテスト前に追加します。
test.ts
import { StructureKind } from "https://deno.land/x/[email protected]/mod.ts";
import { withSource } from "./helper.ts";
import { assertEqualFile } from "./assertEqualFiles.ts";
import { addCustomEntries } from "./mod.ts";
Deno.test(
"addCustomEntries",
{ permissions: { read: true, write: true } },
() =>
withSource(async (source) => {
const constructor = source.addFunction({
name: "hoge",
kind: StructureKind.Function,
statements: 'return ""',
});
addCustomEntries(
[
{
parameters: [{ name: "piyo", type: "string" }],
},
{
parameters: [
{ name: "piyo", type: "string" },
{ name: "foo", type: "number" },
],
},
{
parameters: [
{ name: "foo", type: "number" },
{ name: "bar", type: "number" },
],
},
{
parameters: [
{ name: "piyo", type: "string" },
{ name: "foo", type: "number" },
{ name: "bar", type: "number" },
],
},
],
constructor
);
await source.save();
assertEqualFile(source.getFilePath(), "output.ts.snapshot");
})
);
実行結果
追記の余談
deno test実行時にフラグを渡すことができるのでアップデート用のフラグを追加することでスナップショットの結果を自動で更新できる様にしてみます。
import {
assertEquals,
equal,
} from "https://deno.land/[email protected]/testing/asserts.ts";
import { copy } from "https://deno.land/[email protected]/fs/mod.ts";
export const assertSnapshot = async (
receivedPath: string,
expectedPath: string
) => {
const [received, expected] = await Promise.all([
Deno.readTextFile(receivedPath),
Deno.readTextFile(expectedPath),
]);
if (Deno.args.includes("update_snapshot")) {
if (equal(received, expected)) return;
await copy(receivedPath, expectedPath, { overwrite: true });
} else {
assertEquals(received, expected);
}
};
これで以下の様にスナップショットを更新するためのフラグを追加することができました🎉
deno test test.ts --allow-read --allow-write -- update_snapshot
Author And Source
この問題について(ファイルの読み書きを伴うモジュールのDeno.test), 我々は、より多くの情報をここで見つけました https://zenn.dev/tera_ny/articles/f3772a0893ff17著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Collection and Share based on the CC protocol