JA Getting Started Core Concepts - hiraishikentaro/rails-factorybot-jump GitHub Wiki
はじめに: コア概念
Rails FactoryBot Jump 拡張機能開発における重要な概念と用語の理解。
コア技術
VSCode 拡張アーキテクチャ
ドキュメントリンクプロバイダー: 拡張機能の基盤。VSCode がドキュメント内でクリック可能なリンクを生成する必要があるときにこのインターフェースを呼び出します。
class FactoryLinkProvider implements vscode.DocumentLinkProvider {
provideDocumentLinks(document: vscode.TextDocument): vscode.DocumentLink[];
}
ドキュメントリンク: 関連するアクションを持つクリック可能なテキスト範囲を表す VSCode オブジェクト。
コマンド: 特定のアクション(特定の行にジャンプするなど)を実行するカスタム VSCode コマンド。
FactoryBot 統合
ファクトリー定義: テストオブジェクトの作成方法を定義する Ruby コード。
FactoryBot.define do
factory :user do
name { "John Doe" }
email { "[email protected]" }
end
end
ファクトリー呼び出し: ファクトリーを使用してオブジェクトを作成するテストファイル内のコード。
user = create(:user) # :user ファクトリーを呼び出し
トレイト: 特定の属性を変更するファクトリーのバリエーション。
trait :admin do
admin { true }
end
# 使用法: create(:user, :admin)
パターン認識
ファクトリー呼び出し検出
拡張機能は様々な FactoryBot メソッドパターンを認識します:
基本メソッド:
create(:factory_name)
- データベースに作成・保存build(:factory_name)
- 保存せずにビルドbuild_stubbed(:factory_name)
- スタブされた関連付きでビルド
リストメソッド:
create_list(:factory_name, count)
- 複数のレコードを作成build_list(:factory_name, count)
- 複数のレコードをビルド
構文バリエーション:
# 括弧あり
create(:user)
create(:user, :admin)
# 括弧なし(Ruby スタイル)
create :user
create :user, :admin
ソース: src/providers/factoryLinkProvider.ts
ファクトリー定義検出
ファクトリーパターン: factory :name do
トレイトパターン: trait :name do
拡張機能はこれらのパターンを解析して、利用可能なファクトリーとトレイトの内部キャッシュを構築します。
キャッシングシステム
ファクトリーキャッシュ
目的: 名前によるファクトリー定義の高速検索。
構造: Map<factoryName, {uri, lineNumber}>
例:
{
"user" => { uri: "file:///spec/factories/users.rb", lineNumber: 2 },
"post" => { uri: "file:///spec/factories/posts.rb", lineNumber: 1 }
}
トレイトキャッシュ
目的: ファクトリー内のトレイト定義の高速検索。
構造: Map<"factoryName:traitName", {uri, lineNumber, factory}>
例:
{
"user:admin" => { uri: "file:///spec/factories/users.rb", lineNumber: 6, factory: "user" },
"post:published" => { uri: "file:///spec/factories/posts.rb", lineNumber: 8, factory: "post" }
}
キャッシュライフサイクル
- 初期化: 拡張機能アクティベート時または設定変更時に構築
- 更新: ファイルシステム変更(作成、変更、削除)によってトリガー
- 検索: ドキュメントリンク生成時に使用
- 更新: 必要時に完全再構築
設定システム
ファクトリーパス
目的: 拡張機能にファクトリーファイルの場所を指示。
デフォルト: ["spec/factories/**/*.rb"]
Glob パターン: 柔軟なファイルマッチングのサポート。
{
"rails-factorybot-jump.factoryPaths": [
"spec/factories/**/*.rb", // RSpec 標準
"test/factories/**/*.rb", // Minitest 標準
"lib/factories/**/*.rb" // カスタムロケーション
]
}
パス解決
クロスプラットフォーム: オペレーティングシステム間で一貫した動作のため POSIX パスを使用。
ワークスペース相対: パスは VSCode ワークスペースルートを基準に解決。
ソース: package.json#L55-L65
ファイルシステム統合
ファイル監視
目的: ファイル変更でキャッシュを最新に保つ。
パターン: **/factories/**/*.rb
イベント:
onDidCreate
- 新しいファクトリーファイル追加onDidChange
- 既存のファクトリーファイル変更onDidDelete
- ファクトリーファイル削除
ワークスペース統合
マルチフォルダサポート: VSCode マルチルートワークスペースで動作。
ファイル検出: 信頼性のあるファイルアクセスのため VSCode のワークスペース API を使用。
ナビゲーションメカニクス
リンク生成
- テキストスキャン: 正規表現がドキュメント内のファクトリー呼び出しを検出
- キャッシュ検索: 対応するファクトリー/トレイト定義を検索
- リンク作成: コマンド URI 付きの VSCode DocumentLink を生成
- ユーザーインタラクション: クリックでナビゲーションコマンドをトリガー
コマンド実行
コマンド: rails-factorybot-jump.gotoLine
パラメーター:
uri
: ターゲットファイル URIlineNumber
: ナビゲート先の特定の行
アクション:
- ターゲットドキュメントを開く
- ドキュメント用のエディターを作成
- 特定の行にカーソルを配置
- エディタービューで行を表示
パフォーマンス概念
遅延読み込み
ファクトリー検出: 毎回のアクティベーションではなく、必要時にのみファクトリーファイルをスキャン。
キャッシュ構築: 起動時間を短縮するため最初の使用まで延期。
増分更新
ファイル変更: キャッシュ全体ではなく、影響を受けるキャッシュエントリのみを再構築。
対象更新: ファイルウォッチャーイベントが特定のキャッシュ更新をトリガー。
メモリ効率
Map データ構造: ファクトリーとトレイト解決の O(1) 検索パフォーマンス。
最小ストレージ: 必須情報のみを保存(URI + 行番号)。
最適化されたパーサー: v1.3.0 で導入された改良されたファクトリーパーサーによる高速な解析処理。
キャッシュマネージャー: 専用のキャッシュ管理システムによる効率的なメモリ使用量とファイル監視。
エラーハンドリング概念
グレースフル劣化
ファイル不足: 拡張機能は利用可能なファクトリーファイルで動作を継続。
解析エラー: 機能を壊すことなく問題のある定義をスキップ。
権限問題: ファイルアクセスエラーを適切に処理。
ユーザーエクスペリエンス
エラー通知サービス: v1.3.0 で新たに導入された包括的なエラーハンドリングシステム。
適切なフィードバック: ユーザーに有用な情報を提供する改善されたエラーメッセージ。
デバッグ情報: ユーザーの介入なしにトラブルシューティング用の問題をログ。
フォールバック動作: 可能な場合にベストエフォート機能を提供。
拡張機能ライフサイクル
アクティベーション
トリガー: VSCode が Ruby 言語ファイルを開いたとき。
セットアップ:
- ドキュメントリンクプロバイダーを登録
- コマンドを登録
- ファイルシステムウォッチャーをセットアップ
- ファクトリーキャッシュを初期化(遅延)
非アクティベーション
クリーンアップ:
- サブスクリプションを破棄
- ファイルウォッチャーをクリーンアップ
- キャッシュをクリア
リソース管理: メモリリークやバックグラウンドプロセスがないことを確保。
開発概念
テスト戦略
VSCode 環境: 現実的なテストのため実際の VSCode インスタンスでテストを実行。
モックデータ: ファイルシステムと VSCode API のモック用に Sinon を使用。
テストカバレッジ: コア機能、エッジケース、エラー条件をカバー。
コード構成
プロバイダーパターン: 拡張機能管理とリンク提供の間で関心を分離。
単一責任: 各クラスが一つの明確な目的を持つ。
TypeScript: より良い開発体験と実行時エラーの削減のための強い型付け。