Skip to content

feat: DNCLモード切り替え時にブロック変換のドライラン検証を追加#425

Merged
takaokouji merged 16 commits into
developfrom
feat/dncl-mode-validation
Mar 30, 2026
Merged

feat: DNCLモード切り替え時にブロック変換のドライラン検証を追加#425
takaokouji merged 16 commits into
developfrom
feat/dncl-mode-validation

Conversation

@takaokouji
Copy link
Copy Markdown

@takaokouji takaokouji commented Mar 29, 2026

Summary

DNCLモードに切り替える際、Ruby → DNCL → Ruby → ブロック変換のドライラン検証を追加。変換エラーがあればMonacoエディタにエラーマーカーを表示し、DNCLモードへの遷移を阻止する。

Changes

  • ruby-tab.jsx: handleToggleDnclMode をasync化、ドライラン検証パイプライン追加、dnclValidating state追加、モード切替前に既存エラーをクリア
  • ruby-toolbar.jsx: 検証中にDNCLボタンにSpinner表示、全モード切替ボタンをdisabled、全ボタン/フォームに data-testid 追加
  • target-selector.jsx: data-testid 追加
  • dncl-validation.test.js: 検証ロジックのユニットテスト(10テスト)
  • dncl-mode-validation.test.js: Integration テスト(4テスト)
  • .claude/rules/scratch-gui/e2e-test.md: data-testid 命名規則とPlaywright MCP操作ガイド

How it works

  1. DNCLモード切替ボタンクリック時に既存エラーをクリア
  2. rubyToDncl()dnclToRuby()targetCodeToBlocks() をドライラン実行(apply() は呼ばない=副作用なし)
  3. エラーがあれば「日本語モードでは対応していない記述です:」prefix付きでMonacoマーカーを表示
  4. 検証中はスピナー表示+ボタン群disabled

Note

when_flag_clicked do ... end もDNCL round-tripで壊れる(dnclToRubywhen_flag_clicked@when_flag_clicked に変換するため)。DNCLモードではイベントハンドラなしの純粋なコードのみが有効。

Implementation Steps

  • Phase 1: ドライラン検証ロジック + ローディングUI + ユニットテスト
  • Phase 2: Integration Tests
  • Phase DoD: CI + ブラウザ確認

Definition of Done

  • ユニットテスト pass
  • Integration テスト pass(CI確認)
  • lint pass
  • CI green
  • ブラウザ確認(Playwright MCP):
    • DNCLモードで使えないコード(move(10))で切替時にエラーマーカーが表示される
    • エラーメッセージに「日本語モードでは対応していない記述です:」prefix付き
    • 検証中にスピナー表示(実装済み、目視確認は検証が速く瞬間的)
    • エラー修正後に切替成功(有効コードで dncl に切り替わる)
    • DNCL→Ruby切替は影響なし
    • モード切替時に既存エラーがクリアされる

Test Coverage

  • 10 unit tests in dncl-validation.test.js
  • 4 integration tests in dncl-mode-validation.test.js

Closes #424

When switching to DNCL mode, perform a dry-run validation pipeline:
Ruby → DNCL → Ruby → Blocks conversion (without apply). If the blocks
conversion fails, show errors in Monaco editor with prefix
"日本語モードでは対応していない記述です:" and block the mode switch.

During validation, a spinner is shown on the DNCL button and all mode
toggle buttons are disabled.

Closes #424

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

takaokouji and others added 15 commits March 30, 2026 08:25
Add Selenium-based integration tests verifying:
- Valid code (simple variables + say) allows DNCL switch
- Invalid code (move) blocks switch and shows error markers with prefix
- when_flag_clicked blocks switch (round-trip breaks it)
- DNCL → Ruby switch is not affected by validation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add data-testid to all buttons, inputs, and menu items in ruby-toolbar
and target-selector components. Create e2e-test.md rules documenting
the naming convention and usage patterns with Playwright MCP.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When switching modes, clear any pre-existing error markers first.
New validation errors may appear after the check, but stale errors
from the previous state should not persist.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace hardcoded prefix with a user-friendly localized message
using intl (en, ja, ja-Hira). The error now shows a clear
instruction to use only supported constructs before switching.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…mode

When switching from Code tab to Ruby tab while in DNCL mode:
1. Temporarily switch to furigana mode
2. Generate Ruby code from blocks
3. Automatically attempt DNCL switch with validation
4. If validation fails, stay in furigana mode with error shown
5. If validation succeeds, switch to DNCL mode

Also internationalize the DNCL validation error message (en, ja, ja-Hira)
with a user-friendly message instead of the raw converter error prefix.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The useEffect for pending DNCL switch was blocked by empty code
(falsy check). Also add isVisible to dependencies to ensure the
effect fires when switching back to Ruby tab.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace useEffect-based pending DNCL switch with
requestAnimationFrame + setTimeout to ensure the editor value is
committed after React re-renders. This fixes the case where empty
code (unchanged rubyCodeStr) prevented the useEffect from firing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ruby-tab.jsx is entirely Smalruby-specific, so use a single
file-level marker instead of numerous Start/End block markers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Consolidate marker documentation across rule files:
- code-style.md: add clear rule that Prettier target files
  (= Smalruby-specific) need no markers at all
- smalruby-markers.md: remove duplicated rules, reference
  code-style.md, remove "Smalruby固有ファイル" section
- scratch-vm/development.md: simplify marker section, reference
  code-style.md
- Fix broken reference to scratch-gui/development.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rewrite dncl-mode-validation integration tests to use data-testid
with driver.executeScript instead of seleniumHelper.By.xpath which
was undefined. Update e2e-test.md and testing.md to document the
policy of using data-testid in both Playwright MCP and Selenium
integration tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When DNCL mode is active:
- Block palette shows only DNCL-allowed blocks (DNCL_ALLOWED_BLOCKS
  from dncl-block-filter.js), taking highest filtering priority
- Extension categories are hidden from the palette
- Extension button is visually disabled (50% opacity, not-allowed
  cursor) and shows a localized alert when clicked

Wiring: dnclMode Redux state → containers/gui.jsx →
components/gui.jsx → extension-button.jsx, and
→ containers/blocks.jsx → makeToolboxXML()

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add waitForEditorContent helper to ensure Monaco editor value is
committed before clicking the DNCL button. Increase sleep timeouts
from 3s to 5s for CI environments where Prism WASM loading is slower.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace fixed sleep timeouts with polling wait helpers:
- waitForEditorValue: poll until editor contains expected content
- waitForActiveState: poll until button Active class matches expected

This handles varying CI speeds where WASM loading and async
validation take different amounts of time.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Each test now loads with ?rubyMode=ruby to override any DNCL state
left in localStorage from previous tests. For error tests, wait for
errors to appear instead of waiting for button state, since the
validation might succeed if editor value isn't committed yet.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CI runs in English locale, so check for either Japanese or English
error message string in the integration test.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@takaokouji takaokouji merged commit 83aeef3 into develop Mar 30, 2026
9 checks passed
@takaokouji takaokouji deleted the feat/dncl-mode-validation branch March 30, 2026 01:22
github-actions Bot pushed a commit that referenced this pull request Mar 30, 2026
…e-validation

feat: DNCLモード切り替え時にブロック変換のドライラン検証を追加
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: DNCLモード切り替え時にブロック変換のドライラン検証を追加

1 participant