Getting Started Core Concepts - hiraishikentaro/rails-factorybot-jump GitHub Wiki

Getting Started: Core Concepts

Understanding the essential concepts and terminology for Rails FactoryBot Jump extension development.

Core Technologies

VSCode Extension Architecture

Document Link Provider: The foundation of the extension. VSCode calls this interface whenever it needs to generate clickable links in a document.

class FactoryLinkProvider implements vscode.DocumentLinkProvider {
  provideDocumentLinks(document: vscode.TextDocument): vscode.DocumentLink[];
}

Document Links: VSCode objects that represent clickable text ranges with associated actions.

Commands: Custom VSCode commands that execute specific actions (e.g., jumping to a specific line).

Source: src/extension.ts#L14-L26

FactoryBot Integration

Factory Definitions: Ruby code that defines how to create test objects.

FactoryBot.define do
  factory :user do
    name { "John Doe" }
    email { "[email protected]" }
  end
end

Factory Calls: Code in test files that uses factories to create objects.

user = create(:user)  # Calls the :user factory

Traits: Variations of factories that modify specific attributes.

trait :admin do
  admin { true }
end

# Usage: create(:user, :admin)

Pattern Recognition

Factory Call Detection

The extension recognizes various FactoryBot method patterns:

Basic Methods:

  • create(:factory_name) - Create and save to database
  • build(:factory_name) - Build without saving
  • build_stubbed(:factory_name) - Build with stubbed associations

List Methods:

  • create_list(:factory_name, count) - Create multiple records
  • build_list(:factory_name, count) - Build multiple records

Syntax Variations:

# Parentheses
create(:user)
create(:user, :admin)

# No parentheses (Ruby style)
create :user
create :user, :admin

Source: src/providers/factoryLinkProvider.ts

Factory Definition Detection

Factory Pattern: factory :name do Trait Pattern: trait :name do

The extension parses these patterns to build its internal cache of available factories and traits.

Caching System

Factory Cache

Purpose: Fast lookup of factory definitions by name.

Structure: Map<factoryName, {uri, lineNumber}>

Example:

{
  "user" => { uri: "file:///spec/factories/users.rb", lineNumber: 2 },
  "post" => { uri: "file:///spec/factories/posts.rb", lineNumber: 1 }
}

Trait Cache

Purpose: Fast lookup of trait definitions within factories.

Structure: Map<"factoryName:traitName", {uri, lineNumber, factory}>

Example:

{
  "user:admin" => { uri: "file:///spec/factories/users.rb", lineNumber: 6, factory: "user" },
  "post:published" => { uri: "file:///spec/factories/posts.rb", lineNumber: 8, factory: "post" }
}

Cache Lifecycle

  1. Initialization: Built when extension activates or configuration changes
  2. Updates: Triggered by file system changes (create, modify, delete)
  3. Lookup: Used during document link generation
  4. Refresh: Complete rebuild when needed

Configuration System

Factory Paths

Purpose: Tell the extension where to find factory files.

Default: ["spec/factories/**/*.rb"]

Glob Patterns: Support for flexible file matching.

{
  "rails-factorybot-jump.factoryPaths": [
    "spec/factories/**/*.rb", // RSpec standard
    "test/factories/**/*.rb", // Minitest standard
    "lib/factories/**/*.rb" // Custom location
  ]
}

Path Resolution

Cross-platform: Uses POSIX paths for consistent behavior across operating systems.

Workspace Relative: Paths are resolved relative to the VSCode workspace root.

Source: package.json#L55-L65

File System Integration

File Watching

Purpose: Keep caches up-to-date with file changes.

Pattern: **/factories/**/*.rb

Events:

  • onDidCreate - New factory file added
  • onDidChange - Existing factory file modified
  • onDidDelete - Factory file removed

Workspace Integration

Multi-folder Support: Works with VSCode multi-root workspaces.

File Discovery: Uses VSCode's workspace APIs for reliable file access.

Source: src/extension.ts#L28-L41

Navigation Mechanics

Link Generation

  1. Text Scanning: Regex detects factory calls in document
  2. Cache Lookup: Find corresponding factory/trait definition
  3. Link Creation: Generate VSCode DocumentLink with command URI
  4. User Interaction: Click triggers navigation command

Command Execution

Command: rails-factorybot-jump.gotoLine

Parameters:

  • uri: Target file URI
  • lineNumber: Specific line to navigate to

Actions:

  1. Open target document
  2. Create editor for document
  3. Position cursor at specific line
  4. Reveal line in editor view

Source: src/extension.ts#L14-L26

Performance Concepts

Lazy Loading

Factory Discovery: Only scans factory files when needed, not on every activation.

Cache Building: Deferred until first use to reduce startup time.

Incremental Updates

File Changes: Only rebuild affected cache entries, not entire cache.

Targeted Refresh: File watcher events trigger specific cache updates.

Memory Efficiency

Map Data Structures: O(1) lookup performance for factory and trait resolution.

Minimal Storage: Only store essential information (URI + line number).

Error Handling Concepts

Graceful Degradation

Missing Files: Extension continues working with available factory files.

Parse Errors: Skip problematic definitions without breaking functionality.

Permission Issues: Handle file access errors gracefully.

User Experience

Silent Failures: Don't interrupt workflow with error dialogs.

Debug Information: Log issues for troubleshooting without user intervention.

Fallback Behavior: Provide best-effort functionality when possible.

Extension Lifecycle

Activation

Trigger: When VSCode opens a Ruby language file.

Setup:

  1. Register document link provider
  2. Register commands
  3. Setup file system watcher
  4. Initialize factory cache (lazy)

Deactivation

Cleanup:

  1. Dispose subscriptions
  2. Clean up file watchers
  3. Clear caches

Resource Management: Ensure no memory leaks or background processes.

Source: src/extension.ts#L4-L44

Development Concepts

Testing Strategy

VSCode Environment: Tests run in actual VSCode instance for realistic testing.

Mock Data: Use Sinon for mocking file system and VSCode APIs.

Test Coverage: Cover core functionality, edge cases, and error conditions.

Code Organization

Provider Pattern: Separate concerns between extension management and link provision.

Single Responsibility: Each class has one clear purpose.

TypeScript: Strong typing for better development experience and fewer runtime errors.

Next Steps