Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add: BPM・拍子変更機能を追加 #2303

Open
wants to merge 53 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
b053319
Add: 右クリックメニューを追加
sevenc-nanashi Oct 17, 2024
f548b90
Add: ダイアログを仮置き
sevenc-nanashi Oct 18, 2024
98bfb09
Add: ある程度Storyを追加
sevenc-nanashi Oct 18, 2024
7926faf
Delete: 未使用のimportを削除
sevenc-nanashi Oct 18, 2024
cb2d29e
Add: 削除周りの制御を追加
sevenc-nanashi Oct 18, 2024
4566a67
Add: ルーラーの表示を追加
sevenc-nanashi Oct 18, 2024
d861b88
Add: ルーラーの表示をクリックできるように
sevenc-nanashi Oct 18, 2024
29b5bfa
Add: ツールバーで設定出来るように
sevenc-nanashi Oct 18, 2024
6bd2460
Add: SequencerGridを複数拍子に対応
sevenc-nanashi Oct 19, 2024
ae30925
Add: SequencerRulerを複数拍子に対応
sevenc-nanashi Oct 19, 2024
5d50cb9
Refactor: Container/Presentationに分離
sevenc-nanashi Oct 19, 2024
a2c2d57
Add: Storyを追加
sevenc-nanashi Oct 19, 2024
8d88b6e
Change: uiLockedをpropsで渡せるようにする
sevenc-nanashi Oct 19, 2024
756971a
Add: テストの痕跡を追加
sevenc-nanashi Oct 19, 2024
b4d703e
Refactor: SequencerGridをContainer/Presentationに分離
sevenc-nanashi Oct 19, 2024
9131b71
Add: SequencerGridのStoryを追加
sevenc-nanashi Oct 19, 2024
baeb8b2
Delete: 複数拍子に対応したので削除
sevenc-nanashi Oct 19, 2024
e0d3090
Fix: パスを修正
sevenc-nanashi Oct 19, 2024
d5da914
Add: Storyを追加
sevenc-nanashi Oct 19, 2024
b0ce215
Change: 縦方向に制限する
sevenc-nanashi Oct 19, 2024
dce8a41
Merge: upstream/main -> add/multiple-bpm
sevenc-nanashi Oct 19, 2024
25e694f
[update snapshots]
sevenc-nanashi Oct 19, 2024
74e95b9
(スナップショットを更新)
github-actions[bot] Oct 19, 2024
7458135
Delete: 異物混入を消す
sevenc-nanashi Oct 19, 2024
7d5df06
Delete: デバッグの残骸を削除
sevenc-nanashi Oct 20, 2024
0d56fa9
Merge: upstream/main -> add/multiple-bpm
sevenc-nanashi Oct 20, 2024
9c2e259
Update: スナップショットを更新
sevenc-nanashi Oct 20, 2024
99c1cb4
(スナップショットを更新)
github-actions[bot] Oct 20, 2024
5197afa
Merge: main -> add/multiple-bpm
sevenc-nanashi Oct 26, 2024
97b0685
Change: ContextMenuをDIする
sevenc-nanashi Oct 26, 2024
efa1580
[update snapshots]
sevenc-nanashi Oct 26, 2024
a10557d
Fix: skip-screenshotをつける
sevenc-nanashi Oct 26, 2024
d9c51bd
(スナップショットを更新)
github-actions[bot] Oct 26, 2024
a8da727
Merge: main -> add/multiple-bpm
sevenc-nanashi Oct 29, 2024
2207396
Merge: origin/add/multiple-bpm -> add/multiple-bpm
sevenc-nanashi Oct 29, 2024
5709fd1
Fix: playheadPosition -> playheadTicks
sevenc-nanashi Oct 29, 2024
3f47c2a
Change: Dot記法にする
sevenc-nanashi Oct 29, 2024
33c3b6a
Fix: スナップ線が出ていなかったのを修正
sevenc-nanashi Oct 29, 2024
3237f60
Fix: Storybookが壊れてたのを修正
sevenc-nanashi Oct 29, 2024
512f7b3
Add: snapTypeを指定
sevenc-nanashi Oct 29, 2024
e1f1b76
Change: フォーマットを変える
sevenc-nanashi Oct 29, 2024
c94506f
Change: gridPatternsに色々入れる
sevenc-nanashi Oct 29, 2024
28c7429
Change: atを使う
sevenc-nanashi Oct 29, 2024
ae32da6
Change: tickToMeasureNumberを使う
sevenc-nanashi Oct 29, 2024
bd6e125
Change: patternの計算を修正
sevenc-nanashi Oct 29, 2024
a342a17
Improve: Ruler側も良い感じにする
sevenc-nanashi Oct 30, 2024
24eea03
Change: measureWidthにする
sevenc-nanashi Oct 30, 2024
4798205
Fix: deepを外す
sevenc-nanashi Oct 30, 2024
26a910e
Delete: beatsPerMeasure()を削除
sevenc-nanashi Oct 30, 2024
e2ca101
Refactor: 書き方を変える
sevenc-nanashi Oct 31, 2024
c81cd59
Code: last -> current
sevenc-nanashi Oct 31, 2024
1260cc0
Delete: ヘッダーを消す
sevenc-nanashi Oct 31, 2024
4193ba3
Change: externally taggedにする
sevenc-nanashi Oct 31, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"vite-plugin-node-polyfills": "0.21.0",
"vite-tsconfig-paths": "4.2.1",
"vitest": "2.1.2",
"vue-component-type-helpers": "2.1.6",
"vue-tsc": "2.1.6",
"yargs": "17.2.1"
}
Expand Down
231 changes: 231 additions & 0 deletions src/components/Dialog/TempoOrTimeSignatureChangeDialog.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
import { userEvent, within, expect, fn } from "@storybook/test";
import { Meta, StoryObj } from "@storybook/vue3";

import TempoOrTimeSignatureChangeDialog from "./TempoOrTimeSignatureChangeDialog.vue";

const meta: Meta<typeof TempoOrTimeSignatureChangeDialog> = {
component: TempoOrTimeSignatureChangeDialog,
args: {
modelValue: true,
timeSignatureChange: undefined,
tempoChange: undefined,
mode: "add",
canDeleteTempo: true,
canDeleteTimeSignature: true,

onOk: fn(),
"onUpdate:modelValue": fn(),
},
tags: ["!autodocs"], // ダイアログ系はautodocsのプレビューが正しく表示されないので無効化
};

export default meta;
type Story = StoryObj<typeof meta>;

export const CreateOpened: Story = {
name: "開いている:追加",
args: {
modelValue: true,
mode: "add",
},
};
export const ChangeOpened: Story = {
name: "開いている:変更",
args: {
modelValue: true,
timeSignatureChange: {
beats: 4,
beatType: 4,
},
tempoChange: {
bpm: 120,
},
mode: "edit",
},
};

export const CannotCloseWithoutCreate: Story = {
name: "作成:追加されない状態だと閉じられない",
args: { ...CreateOpened.args },
play: async () => {
const canvas = within(document.body); // ダイアログなので例外的にdocument.bodyを使う

const button = canvas.getByRole("button", { name: /追加する/ });
await expect(button).toBeDisabled();
},
};
export const CannotCloseWithoutChange: Story = {
name: "変更:変更されない状態だと閉じられない",
args: { ...ChangeOpened.args },
play: async () => {
const canvas = within(document.body); // ダイアログなので例外的にdocument.bodyを使う

const button = canvas.getByRole("button", { name: /変更する/ });
await expect(button).toBeDisabled();
},
};
export const CannotCloseIfDeletionDisabled: Story = {
name: "変更:削除不可の場合は削除できない",
args: {
...ChangeOpened.args,
canDeleteTempo: false,
canDeleteTimeSignature: false,
},
play: async () => {
const canvas = within(document.body); // ダイアログなので例外的にdocument.bodyを使う

const bpmToggle = canvas.getByRole("switch", { name: /BPM変更の有無/ });
await expect(bpmToggle.getAttribute("aria-disabled")).toBe("true");

const timeSignatureToggle = canvas.getByRole("switch", {
name: /拍子変更の有無/,
});
await expect(timeSignatureToggle.getAttribute("aria-disabled")).toBe(
"true",
);
},
};
export const SayChangeIfExist: Story = {
name: "変更:どちらかが変更されていれば閉じられる",
args: { ...ChangeOpened.args },
play: async (context) => {
const canvas = within(document.body); // ダイアログなので例外的にdocument.bodyを使う

const okButton = canvas.getByRole("button", { name: /変更する/ });
await context.step("BPMを変更する", async () => {
const input = canvas.getByLabelText("BPM");
await userEvent.clear(input);
await userEvent.type(input, "100");

await expect(okButton).toBeEnabled();

await userEvent.clear(input);
await userEvent.type(input, "120");

await expect(okButton).toBeDisabled();
});

await context.step("拍子を変更する", async () => {
const findOption = (text: string) => {
const maybeElement = canvas
.getAllByRole("option")
.find((el) => el.textContent === text);
if (!maybeElement) throw new Error("Element not found");
return maybeElement;
};
const selectRoot = canvas.getByLabelText("拍子の分子");
await userEvent.click(selectRoot);
await new Promise((resolve) => setTimeout(resolve, 0)); // メニューが開くのを待つ

const option = findOption("3");
await userEvent.click(option);

await expect(okButton).toBeEnabled();

await userEvent.click(selectRoot);
await new Promise((resolve) => setTimeout(resolve, 0));
const option2 = findOption("4");
await userEvent.click(option2);

await expect(okButton).toBeDisabled();
});

await context.step("BPMの存在を変更する", async () => {
const tempoToggle = canvas.getByRole("switch", {
name: /BPM変更の有無/,
});
await userEvent.click(tempoToggle);

await expect(okButton).toBeEnabled();

await userEvent.click(tempoToggle);

await expect(okButton).toBeDisabled();
});

await context.step("拍子の存在を変更する", async () => {
const timeSignatureToggle = canvas.getByRole("switch", {
name: /拍子変更の有無/,
});
await userEvent.click(timeSignatureToggle);

await expect(okButton).toBeEnabled();

await userEvent.click(timeSignatureToggle);

await expect(okButton).toBeDisabled();
});
},
};

export const ClickOk: Story = {
name: "OKボタンを押す:作成",
args: { ...CreateOpened.args },
play: async ({ args }) => {
const canvas = within(document.body); // ダイアログなので例外的にdocument.bodyを使う

const bpmToggle = canvas.getByRole("switch", { name: /BPM変更の有無/ });
await userEvent.click(bpmToggle);
const bpmInput = canvas.getByLabelText("BPM");
await userEvent.clear(bpmInput);
await userEvent.type(bpmInput, "100");

const button = canvas.getByRole("button", { name: /追加する/ });
await userEvent.click(button);

await expect(args["onOk"]).toBeCalledWith({
timeSignatureChange: undefined,
tempoChange: {
bpm: 100,
},
});
await expect(args["onUpdate:modelValue"]).toBeCalledWith(false);
},
};

export const ClickDelete: Story = {
name: "OKボタンを押す:削除",
args: { ...ChangeOpened.args },
play: async ({ args }) => {
const canvas = within(document.body); // ダイアログなので例外的にdocument.bodyを使う

const bpmToggle = canvas.getByRole("switch", { name: /BPM変更の有無/ });
await userEvent.click(bpmToggle);
const timeSignatureToggle = canvas.getByRole("switch", {
name: /拍子変更の有無/,
});
await userEvent.click(timeSignatureToggle);

const button = canvas.getByRole("button", { name: /削除する/ });
await userEvent.click(button);

await expect(args["onOk"]).toBeCalledWith({
timeSignatureChange: undefined,
tempoChange: undefined,
});
await expect(args["onUpdate:modelValue"]).toBeCalledWith(false);
},
};

export const CancelClose: Story = {
name: "キャンセルボタンを押す",
args: { ...ChangeOpened.args },
play: async ({ args }) => {
const canvas = within(document.body); // ダイアログなので例外的にdocument.bodyを使う

const button = canvas.getByRole("button", { name: /キャンセル/ });
await userEvent.click(button);

// ダイアログを閉じるイベントが呼ばれ、onOkは呼ばれない
await expect(args["onOk"]).not.toBeCalled();
await expect(args["onUpdate:modelValue"]).toBeCalledWith(false);
},
};

export const Closed: Story = {
name: "閉じている",
tags: ["skip-screenshot"],
args: {
modelValue: false,
},
};
Loading
Loading